34 Commits
0.0.3 ... main

Author SHA1 Message Date
74f5691e27 chore(changelog): update unreleased changelog 2025-06-14 15:43:12 +00:00
aa25ceb957 chore(workflows): improve git-cliff installation and tagging
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 14s
Build and Publish nightly package / build-and-publish (push) Successful in 31s
- Add `--locked` flag to ensure reproducible git-cliff builds
- Set author and committer dates for consistent tag timestamps
- Fix minor formatting inconsistencies in the workflow file
2025-06-14 17:42:51 +02:00
cda07a61f7 chore(changelog): update unreleased changelog 2025-05-26 15:28:09 +00:00
8d5f168a10 feat(workflows): add release sync to GitHub and clean up
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 6s
Build and Publish nightly package / build-and-publish (push) Successful in 17s
- Integrates Releases Sync Action into the build-and-deploy workflow
- Removes the redundant sync-github workflow for simplification
- Fixes minor formatting issues for consistency
2025-05-26 17:27:56 +02:00
910f1d6eed chore(changelog): update unreleased changelog 2025-05-26 15:15:03 +00:00
de05716b07 fix(workflows): correct token syntax in releases sync action
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 7s
Build and Publish nightly package / build-and-publish (push) Successful in 17s
- Replace `${{ ACTIONS_RUNTIME_TOKEN }}` with `$ACTIONS_RUNTIME_TOKEN`
  to fix incorrect token reference in the workflow configuration.
- Ensures proper authentication for the releases sync action.
2025-05-26 17:14:48 +02:00
1986083586 chore(changelog): update unreleased changelog 2025-05-26 14:47:01 +00:00
e875e781a7 chore(workflows): enable release event handling in sync-github
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 2s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 6s
Build and Publish nightly package / build-and-publish (push) Successful in 16s
2025-05-26 16:46:48 +02:00
c06d22e124 chore(changelog): update unreleased changelog 2025-05-26 14:43:16 +00:00
81b2339ea6 feat(workflows): add Gitea integration to sync action
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Build and Publish nightly package / build-and-publish (push) Successful in 16s
Auto Changelog & Release / changelog-only (push) Successful in 6s
- Introduces Gitea-specific inputs to the releases sync action
  for token, URL, owner, and repository configuration.
- Enhances compatibility with Gitea platforms.
2025-05-26 16:43:00 +02:00
9f3f60fbf2 chore(changelog): update unreleased changelog 2025-05-26 14:38:59 +00:00
45a61134d6 chore(workflows): remove unnecessary checkout step
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 7s
Build and Publish nightly package / build-and-publish (push) Successful in 17s
- Eliminates the redundant checkout step in the sync workflow
- Simplifies the workflow by focusing on the releases sync action
2025-05-26 16:38:46 +02:00
7720343173 chore(changelog): update unreleased changelog 2025-05-26 14:34:58 +00:00
e4785769ea feat(workflows): add GitHub release sync workflow
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 6s
Build and Publish nightly package / build-and-publish (push) Successful in 58s
- Introduces a workflow to synchronize releases with GitHub
- Supports manual triggers with optional tag input
- Utilizes a custom releases sync action for automation
2025-05-26 16:34:43 +02:00
9494fa3619 chore(changelog): update unreleased changelog 2025-05-26 14:33:13 +00:00
8b3117fdca feat(workflows): add GitHub release sync workflow
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Auto Changelog & Release / changelog-only (push) Successful in 6s
Build and Publish nightly package / build-and-publish (push) Successful in 58s
- Introduces a workflow to synchronize releases with GitHub
- Supports manual triggers with optional tag input
- Utilizes a custom releases sync action for automation
2025-05-26 16:32:58 +02:00
8ff8a04437 chore(changelog): update changelog for v0.1.0
All checks were successful
Build and Publish nightly package / build-and-publish (release) Successful in 57s
2025-05-24 11:05:31 +00:00
e5ac928fd4 chore(version): bump version to 0.1.0
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / changelog-only (push) Has been skipped
Auto Changelog & Release / release (push) Successful in 7s
Build and Publish nightly package / build-and-publish (push) Successful in 17s
2025-05-24 13:05:16 +02:00
db8fda15df chore(vscode): customize activity bar and peacock colors 2025-05-24 13:05:16 +02:00
f570a3700b chore(changelog): update unreleased changelog 2025-05-24 10:57:08 +00:00
a9ed247cb4 feat: add project structure and dependency management
All checks were successful
Auto Changelog & Release / detect-version-change (push) Successful in 3s
Auto Changelog & Release / release (push) Has been skipped
Build and Publish nightly package / build-and-publish (push) Successful in 26s
Auto Changelog & Release / changelog-only (push) Successful in 1m14s
- Initialize project with Poetry for dependency management
- Add pyproject.toml and poetry.lock for package configuration
- Refactor existing code into a modular structure under `src/ait`
- Define `ait` as a script entry point for execution
2025-05-24 12:55:36 +02:00
579c70b784 feat(ci): add automated workflows for releases and nightly builds
- Introduce workflows for auto-releases, changelog updates, and nightly builds
- Add scripts for version management, asset uploads, and cleanup tasks
- Remove deprecated GitHub workflow and optimize `.gitignore` entries
- Configure `git-cliff` for enhanced changelog generation with custom rules
2025-05-24 12:55:12 +02:00
6c18e41b00 Add logo to README and new image file
- Added centered logo to `README.md` using `<p>` and `<img>` tags.
- Added new image file `docs/ait.webp`.
2024-08-19 21:03:25 +02:00
3f5c2cec4f Add project time badge to README
- Added a time tracking badge to the top of the README
- Badge source: `https://waka.mpassarello.de/api/badge/MaxP/interval:any/project:Ait?label=Project%20time`
2024-08-19 20:21:18 +02:00
Max P.
7f4c75e606 Update version and configuration settings (#3)
### Modifications
- Updated `VERSION` file from `0.0.5` to `0.0.6`.
- Modified `ait.commit.sample.config.json`:
  - Adjusted `temperature` from 0.7 to 0.6.
- Modified `ait.pull_request.sample.config.json`:
  - Revised the prompt to exclude closing statements.
  - Increased `max_tokens` from 1000 to 2000.
  - Adjusted `temperature` from 0.7 to 0.6.

### Description
This pull request includes updates to the version number and
configuration settings for the commit and pull request message
generator:

1. **Version Update**:
- The version number in the `VERSION` file has been incremented from
`0.0.5` to `0.0.6`.

2. **Commit Sample Config Adjustments**:
- The `temperature` setting in `ait.commit.sample.config.json` has been
lowered from 0.7 to 0.6 to refine the output generation.

3. **Pull Request Sample Config Enhancements**:
- The prompt in `ait.pull_request.sample.config.json` was updated to
exclude any closing statements or generic sentences.
- The `max_tokens` parameter was increased from 1000 to 2000 to allow
for more detailed output.
- The `temperature` setting was also adjusted from 0.7 to 0.6 for
consistent behavior across configurations.
2024-08-19 20:17:47 +02:00
a6dde44a84 Update version number to 0.0.6
- Changed version number in `VERSION` file from `0.0.5` to `0.0.6`
2024-08-19 20:16:05 +02:00
5cc850b8a9 Update PR message config and model settings
- Modified the prompt to exclude closing statements.
- Increased `max_tokens` from 1000 to 2000.
- Adjusted `temperature` from 0.7 to 0.6.
2024-08-19 20:15:29 +02:00
ad14e31b75 Lower temperature setting in commit sample config
- Adjusted `temperature` value from 0.7 to 0.6 in commit sample config file
2024-08-19 20:15:20 +02:00
22972d578c Update version number to 0.0.5
- Changed version in `VERSION` file from `0.0.4` to `0.0.5`
- Note: No newline at end of file
2024-08-19 19:52:03 +02:00
a48f4638c0 Update git log command format
- Modified the `log_command` to use a more detailed pretty format
  - Changed to `--pretty="format:%h%n%ad%n%s%n%n%b%n---%n"`
2024-08-19 19:52:03 +02:00
b50de01653 Add .gitattributes file
- Created `.gitattributes` file
- Configured `* text=auto eol=lf` setting
2024-08-19 19:52:03 +02:00
888acd355f Update version number to 0.0.4
- Changed version in `VERSION` file from `0.0.3` to `0.0.4`
- Ensured no newline at end of file remains consistent
2024-08-19 19:11:25 +02:00
92b4d3872f Add fallback config file search feature
- Added a section on fallback configuration file search in `README.md`
- Explained searching for configuration files in the user's home directory under `~\.ait\*`
- Mentioned the option to provide a user-wide configuration file in the `~\.ait\` directory
2024-08-19 19:11:25 +02:00
b4702c1a72 Update config path resolution logic
- Modify `resolve_config_path` to check for `.json` files.
- First check in the current directory.
- Then check in `.ait` directory in the user's home directory.
- Return filename even if non-existent for later failure handling.
2024-08-19 19:11:25 +02:00
25 changed files with 2080 additions and 97 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto eol=lf

50
.gitea/COMMIT_GPT.md Normal file
View File

@@ -0,0 +1,50 @@
# GPT Prompt
This is a prompt for a GPT model to generate a commit message based on the changes made in the code.
```plaintext
# System
You are a highly precise Git commit message generator for changelog-driven repositories.
Your only task is to read the provided multi-file git diff and generate **one and only one** Conventional Commit message that strictly complies with the rules below.
# Language
You MUST write the entire message in English only.
# Commit Rules
1. Use exactly one of the following lowercase types:
feat, fix, docs, style, refactor, perf, test, chore, revert
2. Optionally add a `(<scope>)` after the type:
• Use a short lowercase identifier (e.g., directory, module, file group)
• Omit if no dominant scope exists
3. Follow this structure:
`type(scope): summary`
• The summary must be in imperative mood
• Max 72 characters
• No trailing period
• Must not contain emojis or casing deviations
4. If the body is needed:
• Add exactly one blank line after the subject
• Use `- ` bullet points
• Each line must be ≤ 72 characters
• Explain what was changed and (if shown in the diff) why
5. Do NOT include:
• `BREAKING CHANGE:` or any `!` markers
• PR numbers, issue IDs, author names, ticket references
• Markdown formatting, emojis, or code blocks
6. The following `chore(...)` patterns MUST be ignored and skipped from changelogs:
chore(changelog), chore(version), chore(release): prepare for, chore(deps), chore(pr), chore(pull)
7. If the commit body contains the word `security`, it will be classified as security-relevant (🛡️), regardless of type.
8. Output MUST consist only of the final commit message, as plain text.
No extra prose, no explanation, no formatting, no examples.
# Now, read the diff and generate the message.
Output only the valid Conventional Commit message, exactly.
```

198
.gitea/HOWTO_RELEASE.md Normal file
View File

@@ -0,0 +1,198 @@
# 📦 HOWTO: Release erstellen mit Auto-Changelog-Workflow
Dieses Repository nutzt einen automatisierten CI/CD-Workflow zur **Versionsverwaltung, Changelog-Generierung und Release-Erstellung**.
Der gesamte Prozess ist deklarativ und läuft automatisch – ausgelöst durch Änderungen an einer Datei: `VERSION`.
---
## 🧭 Was passiert automatisch?
Sobald Änderungen in `main` landen, prüft der Workflow:
- 🔍 **Hat sich die Datei `VERSION` geändert?**
-**Nein** → es wird nur das `CHANGELOG.md` aktualisiert (unreleased Abschnitt)
-**Ja** → es wird:
- ein vollständiger Changelog für diese Version erzeugt
- ein Git-Tag `vX.Y.Z` erstellt
- ein Release in Gitea veröffentlicht (inkl. Beschreibung aus dem Changelog)
---
## ✅ Wie erzeuge ich ein Release?
### 1. Erhöhe die Version in der Datei `VERSION`
Beispiel:
```txt
1.2.3
```
> Diese Datei muss **als eigene Commit-Änderung** erfolgen – idealerweise als letzter Commit in einem PR.
> Die Commit-Nachricht sollte mit `chore(version)` beginnen, damit dieser nicht im Changelog auftaucht.
---
### 2. Mergen in `main`
Sobald `main` den Commit mit neuer `VERSION` enthält, wird automatisch:
- das `CHANGELOG.md` regeneriert und committed
- der neue Git-Tag erstellt (`v1.2.3`)
- ein Gitea Release mit genau diesem Changelog erzeugt
---
## 🛡️ Hinweis zu Tokens & Webhooks
Damit das Release auch korrekt weitere Workflows auslösen kann (z. B. über `on: release`), ist **ein Personal Access Token notwendig**.
### 🔐 Secret: `RELEASE_PUBLISH_TOKEN`
> Lege ein Repository-Secret mit diesem Namen an.
> Es sollte ein **Gitea Personal Access Token** mit folgenden Berechtigungen sein:
- `write:repo`
- `write:release`
- idealerweise: keine Ablaufzeit
Wird dieser Token **nicht** gesetzt, fällt der Workflow auf `ACTIONS_RUNTIME_TOKEN` zurück, aber:
- Release wird trotzdem erstellt
- **⚠️ andere Workflows, die auf `release.published` reagieren, könnten nicht getriggert werden**
---
## 🧪 Debugging-Tipps
- Stelle sicher, dass `VERSION` exakt **eine gültige neue semver-Version** enthält
- Achte auf den Commit-Log: Changelog-Commits sind mit `chore(changelog):` gekennzeichnet
- Verwende nur `main` als Trigger-Zweig
---
## 🧩 Erweiterung
In `upload-assets.yml` kannst du beliebige Build-Artefakte automatisch an das Release anhängen, sobald es veröffentlicht ist.
Dafür:
- liegt das Script `.gitea/scripts/get-release-id.sh`
- sowie `.gitea/scripts/upload-asset.sh` bereit
Mehr dazu in der Datei: `.gitea/workflows/upload-assets.yml`
---
## 🧘 Best Practice
- Changelog-Generierung nie manuell ausführen
- Nur `VERSION` ändern, um ein neues Release auszulösen
- Auf `CHANGELOG.md` nie direkt committen
- Release-Daten niemals per Hand in Gitea pflegen
📎 Alles wird versioniert, automatisiert und reproduzierbar erzeugt.
---
## 🧠 Commit-Gruppierung & Changelog-Erzeugung
Der Changelog wird auf Basis definierter **Commit-Gruppen** erzeugt.
Diese Regeln sind in `cliff.toml` unter `commit_parsers` konfiguriert.
| Prefix / Muster | Gruppe | Beschreibung |
|-------------------------------|---------------------------|--------------------------------------------------|
| `feat:` | 🚀 Features | Neue Funktionalität |
| `fix:` | 🐛 Bug Fixes | Fehlerbehebungen |
| `doc:` | 📚 Documentation | Änderungen an Doku, Readmes etc. |
| `perf:` | ⚡ Performance | Leistungsverbesserungen |
| `refactor:` | 🚜 Refactor | Reorganisation ohne Verhaltensänderung |
| `style:` | 🎨 Styling | Formatierung, Whitespaces, Code-Style |
| `test:` | 🧪 Testing | Neue oder angepasste Tests |
| `ci:` oder `chore:` (ohne Spezifizierung) | ⚙️ Miscellaneous Tasks | CI-Änderungen, Aufgaben, Wartung etc. |
| `chore(changelog)`, `chore(version)`, `chore(release): prepare for`, `chore(deps...)`, `chore(pr)`, `chore(pull)` | *(ignoriert)* | Diese Commits werden im Changelog **ausgelassen** |
| Commit-Body enthält `security` | 🛡️ Security | Sicherheitsrelevante Änderungen |
| `revert:` | ◀️ Revert | Rückgängig gemachte Commits |
| alles andere | 💼 Other | Fallback für nicht erkannte Formate |
### ✍️ Beispiel:
```bash
git commit -m "feat: add login endpoint"
git commit -m "fix: prevent crash on null input"
git commit -m "chore(version): bump to 1.2.3"
```
> Nur die ersten beiden erscheinen im Changelog – der dritte wird **automatisch übersprungen**.
---
## 🧾 Umgang mit `CHANGELOG.md` beim Mergen und Releasen
Wenn du automatisiert einen Changelog mit `git-cliff` erzeugst, ist `CHANGELOG.md` ein **generiertes Artefakt** – und kein handgepflegter Quelltext.
Beim Mergen von Feature-Branches in `main` kann es deshalb zu **unnötigen Konflikten** in dieser Datei kommen, obwohl der Inhalt später sowieso neu erzeugt wird.
---
## 🧼 Umgang mit `CHANGELOG.md` in Feature-Branches
Wenn du mit **Feature-Branches** arbeitest, wird `CHANGELOG.md` dort oft automatisch erzeugt.
Das kann beim späteren Merge in `main` zu **unnötigen Merge-Konflikten** führen.
### ✅ Empfohlene Vorgehensweise
**Bevor du den Branch mit `main` zusammenführst** (Merge oder Cherry-Pick):
```bash
git rm CHANGELOG.md
git commit -m "chore(changelog): remove generated CHANGELOG.md before merge"
git push
```
Dadurch:
* verhinderst du Merge-Konflikte mit `CHANGELOG.md`
* wird die Datei bei Feature-Branches nicht mehr automatisch erzeugt
* bleibt deine Historie sauber und konfliktfrei
> 💡 Der Workflow erzeugt `CHANGELOG.md` automatisch **nur**, wenn:
>
> * die Datei schon vorhanden ist **oder**
> * der Branch `main` heißt
---
## 🧩 Merge-Konflikte verhindern mit `.gitattributes`
Damit Git bei Konflikten in `CHANGELOG.md` **automatisch deine Version bevorzugt**, kannst du folgende Zeile in die Datei `.gitattributes` aufnehmen:
```gitattributes
CHANGELOG.md merge=ours
```
Das bedeutet:
* Beim Merge wird die Version aus dem aktuellen Branch (`ours`) behalten
* Änderungen aus dem Ziel-Branch (`theirs`) werden verworfen
### ✅ So verwendest du es richtig:
1. **Füge die Regel in `main` hinzu**:
```bash
echo "CHANGELOG.md merge=ours" >> .gitattributes
git add .gitattributes
git commit -m "chore(git): prevent merge conflicts in CHANGELOG.md"
git push origin main
```
2. **Hole sie in deinen Feature-Branch**:
```bash
git checkout feature/xyz
git rebase origin/main
```
3. **Ab sofort werden Konflikte in `CHANGELOG.md` automatisch aufgelöst** – lokal.
> ⚠️ Hinweis: Plattformen wie **Gitea, GitHub oder GitLab ignorieren `.gitattributes` beim Merge über die Web-Oberfläche**.
> Führe Merges daher **lokal** durch, wenn du Konflikte verhindern willst.

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
# cleanup_dev_versions.sh - Delete old PyPI dev versions from Gitea package registry
# Required environment variables
USERNAME="${TWINE_USERNAME}"
TOKEN="${TWINE_PASSWORD}"
REPO="${GITHUB_REPOSITORY}" # e.g., maxp/repocat
API_BASE="${GITHUB_API_URL%/}" # Strip trailing slash if present
OWNER="${REPO%%/*}"
PACKAGE_NAME="${REPO##*/}"
API_URL="${API_BASE}/packages/${OWNER}/pypi/${PACKAGE_NAME}"
# Fetch the list of versions
response=$(curl -s -u "$USERNAME:$TOKEN" "$API_URL")
# Extract all .dev versions, sort by creation time
mapfile -t versions_to_delete < <(echo "$response" | jq -r '
map(select(.version | test("\\.dev"))) |
sort_by(.created_at) |
.[0:-1][] |
.version')
# Determine latest version to keep
latest_version=$(echo "$response" | jq -r '
map(select(.version | test("\\.dev"))) |
sort_by(.created_at) |
last.version')
if [[ -z "$latest_version" || ${#versions_to_delete[@]} -eq 0 ]]; then
echo "No old .dev versions to delete."
exit 0
fi
echo "Keeping latest .dev version: $latest_version"
# Delete old .dev versions
for version in "${versions_to_delete[@]}"; do
echo "Deleting old .dev version: $version"
curl -s -X DELETE -u "$USERNAME:$TOKEN" "$API_URL/$version"
done
echo "Cleanup complete."

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
# Eingaben
TAG="$1"
TOKEN="${ACTIONS_RUNTIME_TOKEN:-<fallback_token>}"
REPO="${GITHUB_REPOSITORY:-owner/example}"
API="${GITHUB_API_URL:-https://gitea.example.tld/api/v1}"
OWNER=$(echo "$REPO" | cut -d/ -f1)
NAME=$(echo "$REPO" | cut -d/ -f2)
RESPONSE=$(curl -sf \
-H "Authorization: token $TOKEN" \
"$API/repos/$OWNER/$NAME/releases/tags/$TAG")
RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id')
echo "Release-ID für $TAG ist: $RELEASE_ID"
# Für GitHub Actions als Umgebungsvariable
echo "GT_RELEASE_ID=$RELEASE_ID" >> "$GITHUB_ENV"

View File

@@ -0,0 +1,14 @@
#!/bin/bash
BASE_VERSION=$(cat VERSION)
NIGHTLY_SUFFIX=""
if [[ "$1" == "nightly" ]]; then
# Beispiel: 20240511.1358 → 11. Mai, 13:58 Uhr
NIGHTLY_SUFFIX=".dev$(date +%Y%m%d%H%M)"
fi
FULL_VERSION="${BASE_VERSION}${NIGHTLY_SUFFIX}"
echo "Using version: $FULL_VERSION"
poetry version "$FULL_VERSION"

40
.gitea/scripts/upload-asset.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
# Eingabeparameter
FILE_PATH="$1" # z. B. ./dist/build.zip
CUSTOM_NAME="${2:-}" # optional: anderer Name unter dem das Asset gespeichert werden soll
RELEASE_ID="${GT_RELEASE_ID:-}" # aus Umgebung
# Validierung
if [[ -z "$RELEASE_ID" ]]; then
echo "❌ RELEASE_ID ist nicht gesetzt. Abbruch."
exit 1
fi
if [[ ! -f "$FILE_PATH" ]]; then
echo "❌ Datei '$FILE_PATH' existiert nicht. Abbruch."
exit 1
fi
# Default-Konfiguration
TOKEN="${ACTIONS_RUNTIME_TOKEN:-<fallback_token>}"
REPO="${GITHUB_REPOSITORY:-owner/example}"
API="${GITHUB_API_URL:-https://gitea.example.tld/api/v1}"
# Owner/Repo auflösen
OWNER=$(echo "$REPO" | cut -d/ -f1)
NAME=$(echo "$REPO" | cut -d/ -f2)
# Dateiname setzen
FILENAME="${CUSTOM_NAME:-$(basename "$FILE_PATH")}"
echo "🔼 Uploading '$FILE_PATH' as '$FILENAME' to release ID $RELEASE_ID"
# Upload
curl -sf -X POST \
-H "Authorization: token $TOKEN" \
-F "attachment=@$FILE_PATH" \
"$API/repos/$OWNER/$NAME/releases/$RELEASE_ID/assets?name=$FILENAME"
echo "✅ Upload abgeschlossen: $FILENAME"

View File

@@ -0,0 +1,62 @@
name: Build and Publish nightly package
on:
workflow_dispatch:
push:
branches:
- main
paths-ignore:
- 'CHANGELOG.md'
jobs:
build-and-publish:
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: 🐍 Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: 🔄 Restore cache
uses: https://git.0xmax42.io/actions/cache@v1
with:
key: poetry-v1-${{ runner.os }}-${{ hashFiles('poetry.lock') }}
paths: |
~/.cache/pypoetry
~/.cache/pip
- name: Install Poetry
run: |
pip install poetry
- name: Install Project Dependencies
working-directory: .
run: |
poetry install
- name: Set version from VERSION file (with nightly suffix)
run: ./.gitea/scripts/set_poetry_version.sh nightly
- name: Build Package
working-directory: .
run: |
poetry build
- name: Publish to Gitea Package Registry
working-directory: .
env:
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
run: |
poetry run twine upload --repository-url ${{ secrets.TWINE_URL }} dist/*
- name: Cleanup old dev versions
run: |
.gitea/scripts/cleanup_versions.sh '\.dev'
env:
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}

View File

@@ -0,0 +1,76 @@
name: Build and Publish nightly package
on:
release:
types: [published]
jobs:
build-and-publish:
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.release.tag_name }}
- name: 🐍 Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: 🔄 Restore cache
uses: https://git.0xmax42.io/actions/cache@v1
with:
key: poetry-v1-${{ runner.os }}-${{ hashFiles('poetry.lock') }}
paths: |
~/.cache/pypoetry
~/.cache/pip
- name: Install Poetry
run: |
pip install poetry
- name: Install Project Dependencies
working-directory: .
run: |
poetry install
- name: Build Package
working-directory: .
run: |
poetry build
- name: Get built wheel filename
id: get_whl
run: |
echo "whl_file=$(basename dist/*.whl)" >> $GITHUB_OUTPUT
echo "sdist_file=$(basename dist/*.tar.gz)" >> $GITHUB_OUTPUT
- name: Publish to Gitea Package Registry
working-directory: .
env:
TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
run: |
poetry run twine upload --repository-url ${{ secrets.TWINE_URL }} dist/*
- name: Get Release ID from tag
run: .gitea/scripts/get-release-id.sh "${{ github.event.release.tag_name }}"
- name: Upload assets
run: |
.gitea/scripts/upload-asset.sh ./dist/${{ steps.get_whl.outputs.whl_file }}
.gitea/scripts/upload-asset.sh ./dist/${{ steps.get_whl.outputs.sdist_file }}
- name: Run Releases Sync Action
uses: https://git.0xmax42.io/actions/releases-sync@main
with:
gitea_token: $ACTIONS_RUNTIME_TOKEN
gitea_url: https://git.0xmax42.io
gitea_owner: maxp
gitea_repo: ait
tag_name: ${{ inputs.tag || github.event.release.tag_name }}
github_token: ${{ secrets.SYNC_GITHUB_TOKEN }}
github_owner: 0xMax42
github_repo: ait

View File

@@ -0,0 +1,223 @@
name: Auto Changelog & Release
on:
push:
branches:
- main
- "**"
jobs:
detect-version-change:
runs-on: ubuntu-latest
outputs:
version_changed: ${{ steps.set.outputs.version_changed }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check if VERSION file changed
if: github.ref == 'refs/heads/main'
run: |
echo "🔍 Vergleich mit github.event.before:"
echo "Before: ${{ github.event.before }}"
echo "After: ${{ github.sha }}"
echo "📄 Changed files between before and after:"
git diff --name-only ${{ github.event.before }} ${{ github.sha }} || echo "(diff failed)"
if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^VERSION$'; then
echo "✅ VERSION file was changed"
echo "VERSION_CHANGED=true" >> $GITHUB_ENV
else
echo "ℹ️ VERSION file not changed"
echo "VERSION_CHANGED=false" >> $GITHUB_ENV
fi
- name: Set output (always)
id: set
run: |
echo "version_changed=${VERSION_CHANGED:-false}" >> $GITHUB_OUTPUT
changelog-only:
needs: detect-version-change
if: github.ref != 'refs/heads/main' || needs.detect-version-change.outputs.version_changed == 'false'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set Git Author
run: |
git config user.name "$CI_COMMIT_AUTHOR_NAME"
git config user.email "$CI_COMMIT_AUTHOR_EMAIL"
- name: Read CLIFF_VERSION from cliff.toml
id: cliff_version
run: |
echo "version=$(awk -F '=' '/^# CLIFF_VERSION=/ { gsub(/[" ]/, "", $2); print $2 }' cliff.toml)" >> $GITHUB_OUTPUT
- name: Restore git-cliff cache
id: restore-cliff
uses: https://git.0xmax42.io/actions/cache@v1
with:
key: cargo-cliff-${{ steps.cliff_version.outputs.version }}
paths: |
/root/.cargo/bin
- name: Install git-cliff
if: steps.restore-cliff.outputs.cache-hit != 'true'
run: |
cargo install git-cliff --locked --version "${{ steps.cliff_version.outputs.version }}" --features gitea
- name: Generate unreleased changelog (if file exists or on main)
run: |
if [[ -f CHANGELOG.md || "${GITHUB_REF##refs/heads/}" == "main" ]]; then
echo "Generating CHANGELOG.md..."
git-cliff -c cliff.toml -o CHANGELOG.md
else
echo "CHANGELOG.md does not exist and this is not 'main'. Skipping generation."
fi
- name: Commit updated CHANGELOG
run: |
git add CHANGELOG.md
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore(changelog): update unreleased changelog"
git push origin "${GITHUB_REF##refs/heads/}"
fi
release:
needs: detect-version-change
if: needs.detect-version-change.outputs.version_changed == 'true' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set Git Author
run: |
git config user.name "$CI_COMMIT_AUTHOR_NAME"
git config user.email "$CI_COMMIT_AUTHOR_EMAIL"
- name: Read VERSION
id: version
run: echo "value=$(cat VERSION)" >> $GITHUB_OUTPUT
- name: Read CLIFF_VERSION from cliff.toml
id: cliff_version
run: |
echo "version=$(awk -F '=' '/^# CLIFF_VERSION=/ { gsub(/[" ]/, "", $2); print $2 }' cliff.toml)" >> $GITHUB_OUTPUT
- name: Restore git-cliff cache
id: restore-cliff
uses: https://git.0xmax42.io/actions/cache@v1
with:
key: cargo-cliff-${{ steps.cliff_version.outputs.version }}
paths: |
/root/.cargo/bin
- name: Install git-cliff
if: steps.restore-cliff.outputs.cache-hit != 'true'
run: |
cargo install git-cliff --locked --version "${{ steps.cliff_version.outputs.version }}" --features gitea
- name: Generate changelog for release and tag
id: generate-changelog
run: |
VERSION=${{ steps.version.outputs.value }}
git-cliff -c cliff.toml -t "v$VERSION" -o CHANGELOG.md
BODY=$(mktemp)
ESCAPED_VERSION=$(echo "$VERSION" | sed 's/\./\\./g')
awk -v ver="$ESCAPED_VERSION" '
$0 ~ "^## \\[" ver "\\]" {
print_flag=1
line = $0
sub(/^## /, "", line)
sub(/\\s*\\(.*\\)/, "", line) # entfernt z. B. "(...)" oder "(*)"
print line
next
}
$0 ~ "^## \\[" && $0 !~ "^## \\[" ver "\\]" {
print_flag=0
}
print_flag
' CHANGELOG.md > "$BODY"
echo "changelog_body_path=$BODY" >> $GITHUB_OUTPUT
- name: Commit updated CHANGELOG
run: |
git add CHANGELOG.md
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore(changelog): update changelog for v${{ steps.version.outputs.value }}"
git push origin main
fi
- name: Create Git tag (if not exists)
run: |
VERSION=${{ steps.version.outputs.value }}
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
echo "Tag v$VERSION already exists, skipping tag creation."
else
export GIT_AUTHOR_DATE="$(date --iso-8601=seconds)"
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git tag -a "v$VERSION" -F "${{ steps.generate-changelog.outputs.changelog_body_path }}" --cleanup=verbatim
git push origin "v$VERSION"
fi
- name: Create Gitea release
env:
RELEASE_PUBLISH_TOKEN: ${{ secrets.RELEASE_PUBLISH_TOKEN }}
run: |
VERSION=${{ steps.version.outputs.value }}
BODY_FILE="${{ steps.generate-changelog.outputs.changelog_body_path }}"
OWNER=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f1)
REPO=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f2)
# Token-Auswahl
TOKEN="${RELEASE_PUBLISH_TOKEN:-$ACTIONS_RUNTIME_TOKEN}"
if [[ -z "${RELEASE_PUBLISH_TOKEN:-}" ]]; then
echo "::warning title=Limited Release Propagation::"
echo "RELEASE_PUBLISH_TOKEN is not set. Using ACTIONS_RUNTIME_TOKEN instead."
echo "⚠️ Release events may not trigger other workflows if created with the runtime token."
echo
fi
# Prüfe, ob der Release schon existiert
if curl -sf "$GITHUB_API_URL/repos/$OWNER/$REPO/releases/tags/v$VERSION" \
-H "Authorization: token $TOKEN" > /dev/null; then
echo "🔁 Release for tag v$VERSION already exists, skipping."
exit 0
fi
echo "🚀 Creating Gitea release for v$VERSION"
# Release-Beschreibung vorbereiten
RELEASE_BODY=$(tail -n +2 "$BODY_FILE" | jq -Rs .)
curl -X POST "$GITHUB_API_URL/repos/$OWNER/$REPO/releases" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"tag_name": "v$VERSION",
"target_commitish": "main",
"name": "Release v$VERSION",
"body": $RELEASE_BODY,
"draft": false,
"prerelease": false
}
EOF
echo "✅ Release for tag $VERSION created successfully."

View File

@@ -1,85 +0,0 @@
name: Create Release
on:
push:
branches:
- main
paths:
- "VERSION"
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pyinstaller openai
- name: Get the version
id: get_version
shell: pwsh
run: |
$VERSION = (Get-Content -Path "./VERSION" -Raw).Trim()
echo "VERSION=$VERSION" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8NoBOM -Append
- name: Run auto-py-to-exe
run: |
pyinstaller --noconfirm --onefile --console --name "ait-v${{ env.VERSION }}-winx64" --clean "./ait.py"
- name: Get previous release tag
id: get_previous_release
shell: pwsh
run: |
Write-Host "Fetching previous release tag..."
$previous_tag = git describe --tags --abbrev=0 HEAD^ 2>$null
if (-not $previous_tag) {
Write-Host "No previous tag found, using initial commit."
$previous_tag = git rev-list --max-parents=0 HEAD
}
Write-Host "Previous tag: $previous_tag"
echo "PREVIOUS_TAG=$previous_tag" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Generate release notes
id: generate_notes
shell: pwsh
run: |
Write-Host "Generating release notes from $env:PREVIOUS_TAG to HEAD..."
$repo_url = git config --get remote.origin.url
$notes = git log "$env:PREVIOUS_TAG..HEAD" --pretty=format:"- [`%h`]($repo_url/commit/%H): %s"
Write-Host "Release notes:"
Write-Host "$notes"
"### Changes in this release" | Out-File -FilePath release_notes.md -Encoding utf8
$notes | Out-File -FilePath release_notes.md -Encoding utf8 -Append
- name: Create Tag
id: create_tag
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git tag $env:VERSION
git push origin $env:VERSION
- name: Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.VERSION }}
name: Release ${{ env.VERSION }}
body_path: release_notes.md
files: |
./dist/ait-v${{ env.VERSION }}-winx64.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View File

@@ -5,3 +5,5 @@ ait.*.config.json
dist/
*.spec
build/
**/__pycache__
.gitea/scripts/.env

11
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#d48282",
"activityBar.background": "#d48282",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#b8e7b8",
"activityBarBadge.foreground": "#15202b"
},
"peacock.color": "#c75c5c"
}

35
CHANGELOG.md Normal file
View File

@@ -0,0 +1,35 @@
# Changelog
All notable changes to this project will be documented in this file.
## [unreleased]
### 🚀 Features
- *(workflows)* Add release sync to GitHub and clean up - ([8d5f168](https://git.0xmax42.io/maxp/ait/commit/8d5f168a10e674effe27aab69d348c52f3f8a58f))
- *(workflows)* Add Gitea integration to sync action - ([81b2339](https://git.0xmax42.io/maxp/ait/commit/81b2339ea6d67a73dd62fb67b41db60388750610))
- *(workflows)* Add GitHub release sync workflow - ([e478576](https://git.0xmax42.io/maxp/ait/commit/e4785769eac1dae3945a388dd745fa43555ea4da))
- *(workflows)* Add GitHub release sync workflow - ([8b3117f](https://git.0xmax42.io/maxp/ait/commit/8b3117fdca5c9cd20cfb9ac3cfe0b0f1ee5f9656))
### 🐛 Bug Fixes
- *(workflows)* Correct token syntax in releases sync action - ([de05716](https://git.0xmax42.io/maxp/ait/commit/de05716b072f81351c603d82dafa17ee751b3dad))
### ⚙️ Miscellaneous Tasks
- *(workflows)* Improve git-cliff installation and tagging - ([aa25ceb](https://git.0xmax42.io/maxp/ait/commit/aa25ceb957a07a5267bfd53dea8c58827c9c6840))
- *(workflows)* Enable release event handling in sync-github - ([e875e78](https://git.0xmax42.io/maxp/ait/commit/e875e781a73349e6ac7092e3c599bdfb2526e08e))
- *(workflows)* Remove unnecessary checkout step - ([45a6113](https://git.0xmax42.io/maxp/ait/commit/45a61134d6f8112c710fa1acdfb8c6205da287b4))
## [0.1.0] - 2025-05-24
### 🚀 Features
- Add project structure and dependency management - ([a9ed247](https://git.0xmax42.io/maxp/ait/commit/a9ed247cb486cfc22779da9d6ab2db15f25dc1e6))
- *(ci)* Add automated workflows for releases and nightly builds - ([579c70b](https://git.0xmax42.io/maxp/ait/commit/579c70b784d551426e841253a6d1de4cc53d65bd))
### ⚙️ Miscellaneous Tasks
- *(vscode)* Customize activity bar and peacock colors - ([db8fda1](https://git.0xmax42.io/maxp/ait/commit/db8fda15df7b6a08dbd8eb4167e9b4862712392e))

View File

@@ -1,3 +1,9 @@
![Time](https://waka.mpassarello.de/api/badge/MaxP/interval:any/project:Ait?label=Project%20time)
<p align="center">
<img width="600" src="./docs/ait.webp">
</p>
# AI-Generated Messages from Git Diffs and Logs
This script uses the OpenAI API to generate text based on the outputs of `git diff` and `git log` commands. It can be particularly useful for creating pull request descriptions, commit messages, or any other narrative that requires summarizing changes between different branches or commits in a Git repository.
@@ -60,6 +66,12 @@ python ait.py --config custom
This command will look for a configuration file named `ait.custom.config`.
### Fallback Configuration File search
As a fallback, if no configuration file is found, the script will search for it in the user's home directory under `~\.ait\*`.
You can also provide a user wide configuration file by placing it in the `~\.ait\` directory.
### Command-Line Options
- `--config`: Path to a JSON config file or a keyword to identify a specific config (`ait.<KEYWORD>.config`). Default is `ait.config.json`.

View File

@@ -1 +1 @@
0.0.3
0.1.0

View File

@@ -6,5 +6,5 @@
"prompt": "Generate a concise commit message based on the provided Git diffs, including:\\n - A short and direct subject line (under 50 characters) summarizing the specific changes. No formatting should be used in the subject line.\\n - A brief bullet-point list of the exact modifications made, with basic Markdown formatting allowed in the body.\\n \\n Focus strictly on the changes themselves, avoiding any speculation about the reasons or potential impacts. Ensure that the message is informative enough to understand the changes without needing additional context.",
"model": "gpt-4o",
"max_tokens": 1000,
"temperature": 0.7
"temperature": 0.6
}

View File

@@ -3,8 +3,8 @@
"diff_expression": "main...",
"log_expression": "main...",
"system_prompt": "**You are an automatic pull request message generator and an expert in this field!**",
"prompt": "Generate a concise pull request message based on the provided Git diffs, including:\\n - A short and direct subject line (under 50 characters) summarizing the specific changes. No formatting should be used in the subject line.\\n - A brief bullet-point list of the exact modifications made, with basic Markdown formatting allowed in the body.\\n - A detailed description in Markdown format explaining the changes, their purpose, and any additional context that is relevant for the reviewers.\\n \\n Focus strictly on the changes themselves, avoiding any speculation about the reasons or potential impacts beyond the modifications. Ensure that the message is informative enough to understand the changes and their context for a comprehensive review.",
"prompt": "Generate a concise pull request message based on the provided Git diffs, including:\\n - A short and direct subject line (under 50 characters) summarizing the specific changes. No formatting should be used in the subject line.\\n - A brief bullet-point list of the exact modifications made, with basic Markdown formatting allowed in the body.\\n - A detailed description in Markdown format explaining the changes, and any additional context that is relevant for the reviewers.\\n \\n Focus strictly on the changes themselves, avoiding any speculation about the reasons or potential impacts.\\n **Do not include any closing statements or generic sentences. End the message immediately after providing the necessary details.**",
"model": "gpt-4o",
"max_tokens": 1000,
"temperature": 0.7
"max_tokens": 2000,
"temperature": 0.6
}

104
cliff.toml Normal file
View File

@@ -0,0 +1,104 @@
# CLIFF_VERSION=2.8.0
# git-cliff ~ default configuration file
# https://git-cliff.org/docs/configuration
#
# Lines starting with "#" are comments.
# Configuration options are organized into tables and keys.
# See documentation for more information on available options.
[remote.gitea]
owner = "maxp"
repo = "ait"
[changelog]
# postprocessors
postprocessors = [
{ pattern = '<GITEA_URL>', replace = "https://git.0xmax42.io" }, # replace gitea url
]
# template for the changelog header
header = """
# Changelog\n
All notable changes to this project will be documented in this file.\n
"""
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
{%- macro remote_url() -%}
<GITEA_URL>/{{ remote.gitea.owner }}/{{ remote.gitea.repo }}
{%- endmacro -%}
{% if version %}\
{% if previous.version %}\
## [{{ version | trim_start_matches(pat="v") }}]\
({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% endif %}\
{% else %}\
## [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{% for commit in commits %}
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
{% if commit.breaking %}[**breaking**] {% endif %}\
{{ commit.message | upper_first }} - \
([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% endfor %}
{% endfor %}\n
"""
# template for the changelog footer
footer = """
"""
# remove the leading and trailing s
trim = true
# render body even when there are no releases to process
# render_always = true
# output file path
# output = "test.md"
[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = true
# filter out the commits that are not conventional
filter_unconventional = true
# process each line of a commit as an individual commit
split_commits = false
# regex for preprocessing the commit messages
commit_preprocessors = [
# Replace issue numbers
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
# Check spelling of the commit with https://github.com/crate-ci/typos
# If the spelling is incorrect, it will be automatically fixed.
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
]
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
{ message = "^chore\\(changelog\\)", skip = true },
{ message = "^chore\\(version\\)", skip = true },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore\\(deps.*\\)", skip = true },
{ message = "^chore\\(pr\\)", skip = true },
{ message = "^chore\\(pull\\)", skip = true },
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
{ message = ".*", group = "<!-- 10 -->💼 Other" },
]
# Regex to select git tags that represent releases.
tag_pattern = "v[0-9]+\\.[0-9]+\\.[0-9]+"
# filter out the commits that are not matched by commit parsers
filter_commits = false
# sort the tags topologically
topo_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "newest"

BIN
docs/ait.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

1133
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

21
pyproject.toml Normal file
View File

@@ -0,0 +1,21 @@
[tool.poetry]
name = "ait"
version = "0.1.0"
description = "This script uses the OpenAI API to generate text based on the outputs of git diff and git log commands. It can be particularly useful for creating pull request descriptions, commit messages, or any other narrative that requires summarizing changes between different branches or commits in a Git repository."
authors = ["Max P. <Mail@0xMax42.io>"]
readme = "README.md"
packages = [{ include = "ait", from = "src" }]
[tool.poetry.dependencies]
python = ">=3.12"
openai = "^1.82.0"
[tool.poetry.scripts]
ait = "ait.__main__:main"
[build-system]
requires = ["poetry-core>=2.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.group.dev.dependencies]
twine = "^6.1.0"

0
src/ait/__init__.py Normal file
View File

4
src/ait/__main__.py Normal file
View File

@@ -0,0 +1,4 @@
from ait.ait import main
if __name__ == "__main__":
main()

View File

@@ -22,7 +22,8 @@ def load_config(config_path):
def resolve_config_path(config_input):
"""
Resolves the configuration file path. If a single word is provided,
it looks for a file named 'ait.WORD.config' in the current directory.
it looks for a file named 'ait.WORD.config.json' in the current directory first,
then in a '.ait' directory in the user's home directory.
Parameters:
- config_input (str): The input provided via the command-line argument.
@@ -30,9 +31,24 @@ def resolve_config_path(config_input):
Returns:
- str: The resolved path to the configuration file.
"""
# If it's a keyword, construct the potential filenames
if not config_input.endswith(".json"):
config_input = f"ait.{config_input}.config.json"
return config_input
config_filename = f"ait.{config_input}.config.json"
else:
config_filename = config_input
# Check in the current directory
if os.path.exists(config_filename):
return config_filename
# Check in the user's home directory under .ait/
home_directory = os.path.expanduser("~")
user_config_path = os.path.join(home_directory, ".ait", config_filename)
if os.path.exists(user_config_path):
return user_config_path
# If nothing found, return the filename (it will fail later if non-existent)
return config_filename
def run_git_commands(diff_expression, log_expression):
"""
@@ -48,7 +64,7 @@ def run_git_commands(diff_expression, log_expression):
diff_command = ["git", "diff", diff_expression]
diff_result = subprocess.run(diff_command, capture_output=True, text=True)
log_command = ["git", "log", log_expression, "--pretty=format:%h %s%n%b%n---%n"]
log_command = ["git", "log", log_expression, "--pretty=\"format:%h%n%ad%n%s%n%n%b%n---%n\""]
log_result = subprocess.run(log_command, capture_output=True, text=True)
return diff_result.stdout, log_result.stdout
@@ -90,11 +106,11 @@ def generate_text_from_git_data(diff_output, log_output, system_prompt, user_pro
)
# Extract and return the generated text
generated_text = response.choices[0].message.content.strip()
generated_text = response.choices[0].message.content.strip() # type: ignore
return generated_text
if __name__ == "__main__":
# Default configuration file path
def main():
# Default configuration file path
default_config_path = "ait.config.json"
# Parse command-line arguments