Compare commits

...

1 Commits

Author SHA1 Message Date
Shaun Arman
23c5c4a8be feat(ci): add automated changelog generation via git-cliff
- Add cliff.toml with Tera template: feat/fix/perf/docs/refactor included;
  ci/chore/build/test/style excluded
- Bootstrap CHANGELOG.md from all existing semver tags (v0.1.0–v0.2.49)
- Add changelog job to auto-tag.yml: runs after autotag in parallel with
  build jobs; installs git-cliff v2.7.0 musl binary, generates CHANGELOG.md,
  PATCHes Gitea release body with per-release notes, commits CHANGELOG.md
  to master with [skip ci] to prevent re-trigger, uploads as release asset
- Add set -eu to all changelog job steps
- Null-check RELEASE_ID before API calls; create release if missing
  (race-condition fix: changelog finishes before build jobs create release)
- Add Changelog Generation section to docs/wiki/CICD-Pipeline.md
2026-04-12 21:51:56 -05:00
5 changed files with 531 additions and 0 deletions

View File

@ -65,6 +65,109 @@ jobs:
echo "Tag $NEXT pushed successfully"
changelog:
needs: autotag
runs-on: linux-amd64
container:
image: alpine:latest
steps:
- name: Install dependencies
run: |
set -eu
apk add --no-cache git curl jq
- name: Checkout (full history + all tags)
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
set -eu
git init
git remote add origin \
"http://oauth2:${RELEASE_TOKEN}@172.0.0.29:3000/${GITHUB_REPOSITORY}.git"
git fetch --tags --depth=2147483647 origin
git checkout FETCH_HEAD
git config user.name "gitea-actions[bot]"
git config user.email "gitea-actions@local"
- name: Install git-cliff
run: |
set -eu
CLIFF_VER="2.7.0"
curl -fsSL \
"https://github.com/orhun/git-cliff/releases/download/v${CLIFF_VER}/git-cliff-${CLIFF_VER}-x86_64-unknown-linux-musl.tar.gz" \
| tar -xz --strip-components=1 -C /usr/local/bin \
"git-cliff-${CLIFF_VER}-x86_64-unknown-linux-musl/git-cliff"
- name: Generate changelog
run: |
set -eu
git-cliff --config cliff.toml --output CHANGELOG.md
git-cliff --config cliff.toml --latest --strip all > /tmp/release_body.md
echo "=== Release body preview ==="
cat /tmp/release_body.md
- name: Update Gitea release body
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
set -eu
API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY"
TAG=$(git describe --tags --abbrev=0)
# Create release if it doesn't exist yet (build jobs may still be running)
curl -sf -X POST "$API/releases" \
-H "Authorization: token $RELEASE_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"TFTSR $TAG\",\"body\":\"Release $TAG\",\"draft\":false}" || true
RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \
-H "Authorization: token $RELEASE_TOKEN" | jq -r '.id')
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then
echo "ERROR: Failed to get release ID for $TAG"
exit 1
fi
curl -sf -X PATCH "$API/releases/$RELEASE_ID" \
-H "Authorization: token $RELEASE_TOKEN" \
-H "Content-Type: application/json" \
--data-binary "{\"body\":$(jq -Rs . < /tmp/release_body.md)}"
echo "✓ Release body updated"
- name: Commit CHANGELOG.md to master
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
set -eu
git add CHANGELOG.md
if git diff --staged --quiet; then
echo "No changelog changes"
else
TAG=$(git describe --tags --abbrev=0)
git commit -m "chore: update CHANGELOG.md for ${TAG} [skip ci]"
git push origin HEAD:master
fi
- name: Upload CHANGELOG.md as release asset
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
set -eu
API="http://172.0.0.29:3000/api/v1/repos/$GITHUB_REPOSITORY"
TAG=$(git describe --tags --abbrev=0)
RELEASE_ID=$(curl -sf "$API/releases/tags/$TAG" \
-H "Authorization: token $RELEASE_TOKEN" | jq -r '.id')
if [ -z "$RELEASE_ID" ] || [ "$RELEASE_ID" = "null" ]; then
echo "ERROR: Failed to get release ID for $TAG"
exit 1
fi
EXISTING=$(curl -sf "$API/releases/$RELEASE_ID" \
-H "Authorization: token $RELEASE_TOKEN" \
| jq -r '.assets[]? | select(.name=="CHANGELOG.md") | .id')
[ -n "$EXISTING" ] && curl -sf -X DELETE \
"$API/releases/$RELEASE_ID/assets/$EXISTING" \
-H "Authorization: token $RELEASE_TOKEN"
curl -sf -X POST "$API/releases/$RELEASE_ID/assets" \
-H "Authorization: token $RELEASE_TOKEN" \
-F "attachment=@CHANGELOG.md;filename=CHANGELOG.md"
echo "✓ CHANGELOG.md uploaded"
wiki-sync:
runs-on: linux-amd64
container:

267
CHANGELOG.md Normal file
View File

@ -0,0 +1,267 @@
# Changelog
All notable changes to TFTSR are documented here.
Commit types shown: feat, fix, perf, docs, refactor.
CI, chore, and build changes are excluded.
## [Unreleased]
### Bug Fixes
- Rename GITEA_TOKEN to TF_TOKEN to comply with naming restrictions
- Remove actions/checkout to avoid Node.js dependency
- Use ubuntu container with git installed
- Use actions/checkout with token auth and self-hosted runner
- Use IP addresses for internal services
- Simplified workflow syntax
- Add debugging output for Ollamaresponse
- Correct Ollama URL, API endpoint, and JSON construction in pr-review workflow
- Add diagnostics to identify empty Ollama response root cause
- Use bash shell and remove bash-only substring expansion in pr-review
- Restore migration 014, bump version to 0.2.50, harden pr-review workflow
- Harden pr-review workflow and sync versions to 0.2.50
- Configure container DNS to resolve ollama-ui.tftsr.com
- Harden pr-review workflow — URLs, DNS, correctness and reliability
- Resolve AI review false positives and address high/medium issues
- Replace github.server_url with hardcoded gogs.tftsr.com for container access
- Revert to two-dot diff — three-dot requires merge base unavailable in shallow clone
- Harden pr-review workflow — secret redaction, log safety, auth header
- **ci**: Address AI review — rustup idempotency and cargo --locked
- **ci**: Replace docker:24-cli with alpine + docker-cli in build-images
- **docker**: Add ca-certificates to arm64 base image step 1
- **ci**: Resolve test.yml failures — Cargo.lock, updated test assertions
- **ci**: Address second AI review — || true, ca-certs, cache@v4, key suffixes
- **ci**: Add APPIMAGE_EXTRACT_AND_RUN to build-linux-amd64
### Documentation
- **docker**: Expand rebuild trigger comments to include OpenSSL and Tauri CLI
### Features
- Add automated PR review workflow with Ollama AI
### Performance
- **ci**: Use pre-baked images and add cargo/npm caching
## [0.2.49] — 2026-04-10
### Bug Fixes
- Add missing ai_providers migration (014)
## [0.2.48] — 2026-04-10
### Bug Fixes
- Lint fixes and formatting cleanup
### Features
- Support GenAI datastore file uploads and fix paste image upload
## [0.2.47] — 2026-04-09
### Bug Fixes
- Use 'provider' argument name to match Rust command signature
## [0.2.46] — 2026-04-09
### Bug Fixes
- Add @types/testing-library__react for TypeScript compilation
### Update
- Node_modules from npm install
## [0.2.45] — 2026-04-09
### Bug Fixes
- Force single test thread for Rust tests to eliminate race conditions
## [0.2.43] — 2026-04-09
### Bug Fixes
- Fix encryption test race condition with parallel tests
- OpenWebUI provider connection and missing command registrations
### Features
- Add image attachment support with PII detection
## [0.2.42] — 2026-04-07
### Documentation
- Add AGENTS.md and SECURITY_AUDIT.md
## [0.2.41] — 2026-04-07
### Bug Fixes
- **db,auth**: Auto-generate encryption keys for release builds
- **lint**: Use inline format args in auth.rs
- **lint**: Resolve all clippy warnings for CI compliance
- **fmt**: Apply rustfmt formatting to webview_fetch.rs
- **types**: Replace normalizeApiFormat() calls with direct value
### Documentation
- **architecture**: Add C4 diagrams, ADRs, and architecture overview
### Features
- **ai**: Add tool-calling and integration search as AI data source
## [0.2.40] — 2026-04-06
### Bug Fixes
- Add user_id support and OAuth shell permission (v0.2.6)
- Use Wiki secret for authenticated wiki sync (v0.2.8)
- Persist integration settings and implement persistent browser windows
- ARM64 build uses native target instead of cross-compile
- Resolve clippy uninlined_format_args in integrations and related modules
- Resolve clippy format-args failures and OpenSSL vendoring issue
- Resolve macOS bundle path after app rename
- **ci**: Make release artifacts reliable across platforms
- **ci**: Harden release asset uploads for reruns
- **ci**: Trigger release workflow from auto-tag pushes
- **ci**: Guarantee release jobs run after auto-tag
- **ci**: Use stable auto-tag job outputs for release fanout
- **ci**: Run post-tag release builds without job-output gating
- **ci**: Repair auto-tag workflow yaml so jobs trigger
- **ci**: Force explicit linux arm64 target for release artifacts
- **ci**: Run linux arm release natively and enforce arm artifacts
- **ci**: Unblock release jobs and namespace linux artifacts by arch
- **security**: Harden secret handling and audit integrity
- **pii**: Remove lookahead from hostname regex, fix fmt in analysis test
- **security**: Enforce PII redaction before AI log transmission
- **ci**: Unblock release jobs and namespace linux artifacts by arch
- **ci**: Fix arm64 cross-compile, drop cargo install tauri-cli, move wiki-sync
- **ci**: Rebuild apt sources with per-arch entries before arm64 cross-compile install
- **ci**: Add workflow_dispatch and concurrency guard to auto-tag
- **ci**: Replace heredoc with printf in arm64 install step
- **ci**: Switch build-linux-arm64 to Ubuntu 22.04 with ports mirror
- **ci**: Remove GITHUB_PATH append that was breaking arm64 install step
- **ci**: Use POSIX dot instead of source in arm64 build step
- **ci**: Add make to arm64 host tools for OpenSSL vendored build
- **ci**: Set APPIMAGE_EXTRACT_AND_RUN=1 for arm64 AppImage bundling
- **ci**: Restrict arm64 bundles to deb,rpm — skip AppImage
- **security**: Add path canonicalization and actionable permission error in install_ollama_from_bundle
- **ci**: Skip Ollama download on macOS build — runner has no access to GitHub binary assets
- **ci**: Remove all Ollama bundle download steps — use UI download button instead
- **ci**: Remove explicit docker.sock mount — act_runner mounts it automatically
### Documentation
- Add Custom REST provider documentation
- Update wiki for v0.2.6 - integrations and Custom REST provider
- Update CI pipeline wiki and add ticket summary for arm64 fix
### Features
- Implement Confluence, ServiceNow, and Azure DevOps REST API clients
- Add Custom REST provider support
- Add automatic wiki sync to CI workflow (v0.2.7)
- Add temperature and max_tokens support for Custom REST providers (v0.2.9)
- Add multi-mode authentication for integrations (v0.2.10)
- Complete webview cookie extraction implementation
- Add custom_rest provider mode and rebrand application name
- **rebrand**: Rename binary to trcaa and auto-generate DB key
- **ui**: Fix model dropdown, auth prefill, PII persistence, theme toggle, and Ollama bundle
- **ci**: Add persistent pre-baked Docker builder images
### Refactoring
- **ci**: Remove standalone release workflow
- **ollama**: Remove download/install buttons — show plain install instructions only
## [0.2.4] — 2026-04-03
### Features
- Implement OAuth2 token exchange and AES-256-GCM encryption
- Add OAuth2 Tauri commands for integration authentication
- Implement OAuth2 callback server with automatic token exchange
- Add OAuth2 frontend UI and complete integration flow
## [0.2.3] — 2026-04-03
### Bug Fixes
- Improve Cancel button contrast in AI disclaimer modal
### Features
- Add database schema for integration credentials and config
## [0.2.1] — 2026-04-03
### Bug Fixes
- Button text visibility, toggle contrast, create_issue IPC, ad-hoc codesign
- Dropdown text invisible on macOS + correct codesign order for DMG
- Add explicit text-foreground to SelectTrigger, SelectValue, and SelectItem
- Ollama detection, install guide UI, and AI Providers auto-fill
- Provider test FK error, model pull white screen, RECOMMENDED badge
- Provider routing uses provider_type, Active badge, fmt
- Navigate to /logs after issue creation, fix dashboard category display
- Dashboard shows — while loading, exposes errors, adds refresh button
- ListIssuesCmd was sending {query} but Rust expects {filter} — caused dashboard to always show 0 open issues
- Arm64 linux cross-compilation — add multiarch and pkg-config env vars
- Close from chat works before issue loads; save user reason as resolution step; dynamic version
- DomainPrompts closing brace too early; arm64 use native platform image
- UI contrast issues and ARM64 build failure
- Remove Woodpecker CI and fix Gitea Actions ARM64 build
- UI visibility issues, export errors, filtering, and audit log enhancement
- ARM64 build native compilation instead of cross-compilation
- Improve release artifact upload error handling
- Install jq in Linux/Windows build containers
- Improve download button visibility and add DOCX export
- Implement native DOCX export without pandoc dependency
### Documentation
- Add LiteLLM + AWS Bedrock integration guide
### Features
- Add macOS arm64 act_runner and release build job
- Auto-increment patch tag on every merge to master
- Inline file/screenshot attachment in triage chat
- Close issues, restore history, auto-save resolution steps
- Expand domains to 13 — add Telephony, Security/Vault, Public Safety, Application, Automation/CI-CD
- Add HPE, Dell, Identity domains + expand k8s/security/observability/VESTA NXT
- Add AI disclaimer modal before creating new issues
## [0.1.1] — 2026-03-30
### Bug Fixes
- Remove unused tauri-plugin-updater + SQLCipher 16KB page size
- Prevent WebKit/GTK system theme from overriding input text colors on Linux
- Set SQLCipher cipher_page_size BEFORE first database access
### Documentation
- Update README, wiki, and UI version to v0.1.1
## [0.1.0] — 2026-03-29
### Bug Fixes
- Resolve all clippy lints (uninlined format args, range::contains, push_str single chars)
- Inline format args for Rust 1.88 clippy compatibility
- Retain GPU-VRAM-eligible models in recommender even when RAM is low
- Use alpine/git with explicit checkout for tag-based release builds
- Set CI=true for cargo tauri build — Woodpecker sets CI=woodpecker which Tauri CLI rejects
- Arm64 cross-compilation — add multiarch pkg-config sysroot setup
- Remove arm64 from release pipeline — webkit2gtk multiarch conflict on x86_64 host
- Write artifacts to workspace (shared between steps), not /artifacts/
- Upload step needs gogs_default network to reach Gogs API (host firewall blocks default bridge)
- Use bundled-sqlcipher-vendored-openssl for portable Windows cross-compilation
- Add make to windows build step (required by vendored OpenSSL)
- Replace empty icon placeholder files with real app icons
- Suppress MinGW auto-export to resolve Windows DLL ordinal overflow
- Use when: platform: for arm64 step routing (Woodpecker 0.15.4 compat)
- Remove unused tauri-plugin-cli causing startup crash
- Use $GITHUB_REF_NAME env var instead of ${{ github.ref_name }} expression
### Documentation
- Update PLAN.md with accurate implementation status
- Add CLAUDE.md with development guidance
- Add wiki source files and CI auto-sync pipeline
- Update PLAN.md - Phase 11 complete, redact token references
- Update README and wiki for v0.1.0-alpha release
- Remove broken arm64 CI step, document Woodpecker 0.15.4 limitation
- Update README and wiki for Gitea Actions migration
### Features
- Add Windows amd64 cross-compile to release pipeline; add arm64 QEMU agent
- Add native linux/arm64 release build step
### Security
- Rotate exposed token, redact from PLAN.md, add secret patterns to .gitignore
## [0.1.0-test] — 2026-03-15
### Features
- Initial implementation of TFTSR IT Triage & RCA application

41
cliff.toml Normal file
View File

@ -0,0 +1,41 @@
[changelog]
header = """
# Changelog
All notable changes to TFTSR are documented here.
Commit types shown: feat, fix, perf, docs, refactor.
CI, chore, and build changes are excluded.
"""
body = """
{% if version -%}
## [{{ version | trim_start_matches(pat="v") }}] — {{ timestamp | date(format="%Y-%m-%d") }}
{% else -%}
## [Unreleased]
{% endif -%}
{% for group, commits in commits | group_by(attribute="group") -%}
### {{ group | upper_first }}
{% for commit in commits -%}
- {% if commit.scope %}**{{ commit.scope }}**: {% endif %}{{ commit.message | upper_first }}
{% endfor %}
{% endfor %}
"""
footer = ""
trim = true
[git]
conventional_commits = true
filter_unconventional = true
tag_pattern = "v[0-9].*"
ignore_tags = "rc|alpha|beta"
sort_commits = "oldest"
commit_parsers = [
{ message = "^feat", group = "Features" },
{ message = "^fix", group = "Bug Fixes" },
{ message = "^perf", group = "Performance" },
{ message = "^docs", group = "Documentation" },
{ message = "^refactor", group = "Refactoring" },
{ message = "^ci|^chore|^build|^test|^style", skip = true },
]

View File

@ -257,6 +257,52 @@ UPDATE protect_branch SET protected=true, require_pull_request=true WHERE repo_i
---
## Changelog Generation
Changelogs are generated automatically by **git-cliff** on every release.
Configuration lives in `cliff.toml` at the repo root.
### How it works
A `changelog` job in `auto-tag.yml` runs in parallel with the build jobs, immediately
after `autotag` completes:
1. Clones the full repo history with all tags (`--depth=2147483647` — git-cliff needs
every tag to compute version boundaries).
2. Downloads the git-cliff v2.7.0 static musl binary (~5 MB, no image change needed).
3. Runs `git-cliff --output CHANGELOG.md` to regenerate the full cumulative changelog.
4. Runs `git-cliff --latest --strip all` to produce release notes for the new tag only.
5. PATCHes the Gitea release body with those notes (replaces the static `"Release vX.Y.Z"`).
6. Commits `CHANGELOG.md` to master with `[skip ci]` appended to the message.
The `[skip ci]` token prevents `auto-tag.yml` from re-triggering on the CHANGELOG commit.
7. Uploads `CHANGELOG.md` as a release asset (replaces any previous version).
### cliff.toml reference
| Setting | Value |
|---------|-------|
| `tag_pattern` | `v[0-9].*` |
| `ignore_tags` | `rc\|alpha\|beta` |
| `filter_unconventional` | `true` — non-conventional commits are dropped |
| Included types | `feat`, `fix`, `perf`, `docs`, `refactor` |
| Excluded types | `ci`, `chore`, `build`, `test`, `style` |
### Loop prevention
The `[skip ci]` suffix on the CHANGELOG commit message is recognised by Gitea Actions
and causes the workflow to be skipped for that push. Without it, the CHANGELOG commit
would trigger `auto-tag.yml` again, incrementing the patch version forever.
### Bootstrap
The initial `CHANGELOG.md` was generated locally before the first PR:
```sh
git-cliff --config cliff.toml --output CHANGELOG.md
```
Subsequent runs are fully automated by CI.
---
## Known Issues & Fixes
### Debian Multiarch Breaks arm64 Cross-Compile (`held broken packages`)

View File

@ -0,0 +1,74 @@
# feat: Automated Changelog via git-cliff
## Description
Introduces automated changelog generation using **git-cliff**, a tool that parses
conventional commits and produces formatted Markdown changelogs.
Previously, every Gitea release body contained only the static text `"Release vX.Y.Z"`.
With this change, releases display a categorised, human-readable list of all commits
since the previous version.
**Root cause / motivation:** No changelog tooling existed. The project follows
Conventional Commits throughout but the information was never surfaced to end-users.
**Files changed:**
- `cliff.toml` (new) — git-cliff configuration; defines commit parsers, ignored tags,
output template, and which commit types appear in the changelog
- `CHANGELOG.md` (new) — bootstrapped from all existing tags; maintained by CI going forward
- `.gitea/workflows/auto-tag.yml` — new `changelog` job that runs after `autotag`
- `docs/wiki/CICD-Pipeline.md` — "Changelog Generation" section added
## Acceptance Criteria
- [ ] `cliff.toml` present at repo root with working Tera template
- [ ] `CHANGELOG.md` present at repo root, bootstrapped from all existing semver tags
- [ ] `changelog` job in `auto-tag.yml` runs after `autotag` (parallel with build jobs)
- [ ] Each Gitea release body shows grouped conventional-commit entries instead of
static `"Release vX.Y.Z"`
- [ ] `CHANGELOG.md` committed to master on every release with `[skip ci]` suffix
(no infinite re-trigger loop)
- [ ] `CHANGELOG.md` uploaded as a downloadable release asset
- [ ] CI/chore/build/test/style commits excluded from changelog output
- [ ] `docs/wiki/CICD-Pipeline.md` documents the changelog generation process
## Work Implemented
### `cliff.toml`
- Tera template with proper whitespace control (`-%}` / `{%- `) for clean output
- Included commit types: `feat`, `fix`, `perf`, `docs`, `refactor`
- Excluded commit types: `ci`, `chore`, `build`, `test`, `style`
- `ignore_tags = "rc|alpha|beta"` — pre-release tags excluded from version boundaries
- `filter_unconventional = true` — non-conventional commits dropped silently
- `sort_commits = "oldest"` — chronological order within each version
### `CHANGELOG.md`
- Bootstrapped locally using git-cliff v2.7.0 (aarch64 musl binary)
- Covers all tagged versions from `v0.1.0` through `v0.2.49` plus `[Unreleased]`
- 267 lines covering the full project history
### `.gitea/workflows/auto-tag.yml``changelog` job
- `needs: autotag` — waits for the new tag to exist before running
- Full history clone: `git fetch --tags --depth=2147483647` so git-cliff can resolve
all version boundaries
- git-cliff v2.7.0 downloaded as a static x86_64 musl binary (~5 MB); no custom
image required
- Generates full `CHANGELOG.md` and per-release notes (`--latest --strip all`)
- PATCHes the Gitea release body via API with JSON-safe escaping (`jq -Rs .`)
- Commits `CHANGELOG.md` to master with `[skip ci]` to prevent workflow re-trigger
- Deletes any existing `CHANGELOG.md` asset before re-uploading (rerun-safe)
- Runs in parallel with all build jobs — no added wall-clock latency
### `docs/wiki/CICD-Pipeline.md`
- Added "Changelog Generation" section before "Known Issues & Fixes"
- Describes the five-step process, cliff.toml settings, and loop prevention mechanism
## Testing Needed
- [ ] Merge this PR to master; verify `changelog` CI job succeeds in Gitea Actions
- [ ] Check Gitea release body for the new version tag — should show grouped commit list
- [ ] Verify `CHANGELOG.md` was committed to master (check git log after CI runs)
- [ ] Verify `CHANGELOG.md` appears as a downloadable asset on the release page
- [ ] Push a subsequent commit to master; confirm the `[skip ci]` CHANGELOG commit does
NOT trigger a second run of `auto-tag.yml`
- [ ] Confirm CI/chore commits are absent from the release body