From fc55dfe9a83d44f837f113d1049aab5d61010e60 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 31 Mar 2026 13:01:56 -0600 Subject: [PATCH] fix(ci): make releases manual and gate heavy workflows --- .github/workflows/build.yml | 20 +++++++---- .github/workflows/release.yml | 67 +++++++++++++++++++++++++---------- docs/releases.md | 13 +++++-- 3 files changed, 71 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8433cc6..496b1e3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,6 +55,7 @@ jobs: build_related: ${{ steps.filter.outputs.build_related }} template_assets_related: ${{ steps.filter.outputs.template_assets_related }} renovate_related: ${{ steps.filter.outputs.renovate_related }} + tooling_related: ${{ steps.filter.outputs.tooling_related }} steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -74,6 +75,7 @@ jobs: echo "build_related=true" >> "${GITHUB_OUTPUT}" echo "template_assets_related=true" >> "${GITHUB_OUTPUT}" echo "renovate_related=true" >> "${GITHUB_OUTPUT}" + echo "tooling_related=true" >> "${GITHUB_OUTPUT}" exit 0 fi @@ -90,6 +92,7 @@ jobs: echo "build_related=true" >> "${GITHUB_OUTPUT}" echo "template_assets_related=true" >> "${GITHUB_OUTPUT}" echo "renovate_related=true" >> "${GITHUB_OUTPUT}" + echo "tooling_related=true" >> "${GITHUB_OUTPUT}" exit 0 fi @@ -99,6 +102,7 @@ jobs: echo "build_related=true" >> "${GITHUB_OUTPUT}" echo "template_assets_related=true" >> "${GITHUB_OUTPUT}" echo "renovate_related=true" >> "${GITHUB_OUTPUT}" + echo "tooling_related=true" >> "${GITHUB_OUTPUT}" exit 0 fi else @@ -107,6 +111,7 @@ jobs: echo "build_related=true" >> "${GITHUB_OUTPUT}" echo "template_assets_related=true" >> "${GITHUB_OUTPUT}" echo "renovate_related=true" >> "${GITHUB_OUTPUT}" + echo "tooling_related=true" >> "${GITHUB_OUTPUT}" exit 0 fi fi @@ -116,21 +121,21 @@ jobs: build_related=false template_assets_related=false renovate_related=false + tooling_related=false while IFS= read -r path; do [[ -z "${path}" ]] && continue case "${path}" in - Dockerfile|upstream.toml|rootfs/*|scripts/*) + Dockerfile|upstream.toml|rootfs/*) build_related=true ;; *.xml|assets/*.png) template_assets_related=true ;; - renovate.json) - renovate_related=true + scripts/*|.github/workflows/*) + tooling_related=true ;; - .github/workflows/*) - build_related=true + renovate.json) renovate_related=true ;; esac @@ -139,10 +144,11 @@ jobs: echo "build_related=${build_related}" >> "${GITHUB_OUTPUT}" echo "template_assets_related=${template_assets_related}" >> "${GITHUB_OUTPUT}" echo "renovate_related=${renovate_related}" >> "${GITHUB_OUTPUT}" + echo "tooling_related=${tooling_related}" >> "${GITHUB_OUTPUT}" validate-repo: needs: detect-changes - if: ${{ needs.detect-changes.outputs.build_related == 'true' || needs.detect-changes.outputs.template_assets_related == 'true' || needs.detect-changes.outputs.renovate_related == 'true' }} + if: ${{ needs.detect-changes.outputs.build_related == 'true' || needs.detect-changes.outputs.template_assets_related == 'true' || needs.detect-changes.outputs.renovate_related == 'true' || needs.detect-changes.outputs.tooling_related == 'true' }} runs-on: ubuntu-latest permissions: contents: read @@ -151,7 +157,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Validate shell and python scripts - if: ${{ needs.detect-changes.outputs.build_related == 'true' }} + if: ${{ needs.detect-changes.outputs.build_related == 'true' || needs.detect-changes.outputs.tooling_related == 'true' }} run: | bash -n scripts/smoke-test.sh PYTHONPYCACHEPREFIX=/tmp/khoj-aio-pyc python3 -m py_compile scripts/check-upstream.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d69d6d..bd914c5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,12 +2,19 @@ name: Release / Khoj-AIO on: workflow_dispatch: - pull_request_target: - types: [closed] + inputs: + action: + description: "Release action to run" + required: true + default: prepare + type: choice + options: + - prepare + - publish jobs: prepare-release: - if: ${{ github.ref == 'refs/heads/main' }} + if: ${{ github.event.inputs.action == 'prepare' && github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest permissions: contents: write @@ -17,6 +24,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + - name: Install git-cliff env: GIT_CLIFF_VERSION: 2.12.0 @@ -25,21 +33,28 @@ jobs: curl -fsSL -o "/tmp/${archive}" "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/${archive}" tar -xzf "/tmp/${archive}" -C /tmp install "/tmp/git-cliff-${GIT_CLIFF_VERSION}/git-cliff" /usr/local/bin/git-cliff + - name: Check for unreleased changes id: changes run: | echo "has_changes=$(python3 scripts/release.py has-unreleased-changes)" >> "${GITHUB_OUTPUT}" + - name: Compute release version id: version if: steps.changes.outputs.has_changes == 'true' - run: echo "release_version=$(python3 scripts/release.py next-version)" >> "${GITHUB_OUTPUT}" + run: | + release_version="$(python3 scripts/release.py next-version)" + echo "release_version=${release_version}" >> "${GITHUB_OUTPUT}" + - name: Generate changelog if: steps.changes.outputs.has_changes == 'true' env: GITHUB_REPO: ${{ github.repository }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_VERSION: ${{ steps.version.outputs.release_version }} - run: git-cliff --config cliff.toml --tag "${RELEASE_VERSION}" --output CHANGELOG.md + run: | + git-cliff --config cliff.toml --tag "${RELEASE_VERSION}" --output CHANGELOG.md + - name: Create release PR if: steps.changes.outputs.has_changes == 'true' uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 @@ -48,28 +63,36 @@ jobs: title: "chore(release): ${{ steps.version.outputs.release_version }}" body: | This PR prepares `${{ steps.version.outputs.release_version }}`. + + - updates `CHANGELOG.md` with `git-cliff` + - is intended to be merged to `main` + - requires a separate manual `publish` run after merge branch: "release/${{ steps.version.outputs.release_version }}" delete-branch: true - publish-release-on-merge: - if: "${{ github.event_name == 'pull_request_target' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' && startsWith(github.event.pull_request.title, 'chore(release): ') }}" + publish-release: + if: ${{ github.event.inputs.action == 'publish' && github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest permissions: contents: write steps: - - name: Checkout merge commit + - name: Checkout main uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: ${{ github.event.pull_request.merge_commit_sha }} fetch-depth: 0 + - name: Determine release version id: version - env: - PR_TITLE: ${{ github.event.pull_request.title }} run: | - release_version="${PR_TITLE#chore(release): }" + release_version="$(python3 scripts/release.py latest-changelog-version)" echo "release_version=${release_version}" >> "${GITHUB_OUTPUT}" - test "$(python3 scripts/release.py latest-changelog-version)" = "${release_version}" + release_commit="$(git log --format='%H%x09%s' HEAD | awk -F '\t' -v title="chore(release): ${release_version}" '$2 == title {print $1; exit}')" + if [[ -z "${release_commit}" ]]; then + echo "Unable to find a merged release commit for ${release_version} on main." >&2 + exit 1 + fi + echo "release_commit=${release_commit}" >> "${GITHUB_OUTPUT}" + - name: Extract release notes id: notes env: @@ -80,24 +103,30 @@ jobs: python3 scripts/release.py extract-release-notes "${RELEASE_VERSION}" echo "EOF" } >> "${GITHUB_OUTPUT}" + - name: Create Git tag if missing env: RELEASE_VERSION: ${{ steps.version.outputs.release_version }} - MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }} + RELEASE_COMMIT: ${{ steps.version.outputs.release_commit }} run: | - if git rev-parse "${RELEASE_VERSION}" >/dev/null 2>&1; then exit 0; fi + if git rev-parse "${RELEASE_VERSION}" >/dev/null 2>&1; then + exit 0 + fi git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag "${RELEASE_VERSION}" "${MERGE_SHA}" + git tag "${RELEASE_VERSION}" "${RELEASE_COMMIT}" git push origin "${RELEASE_VERSION}" + - name: Publish GitHub release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_VERSION: ${{ steps.version.outputs.release_version }} RELEASE_NOTES: ${{ steps.notes.outputs.release_notes }} - MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }} + RELEASE_COMMIT: ${{ steps.version.outputs.release_commit }} run: | - if gh release view "${RELEASE_VERSION}" >/dev/null 2>&1; then exit 0; fi + if gh release view "${RELEASE_VERSION}" >/dev/null 2>&1; then + exit 0 + fi notes_file="$(mktemp)" printf '%s\n' "${RELEASE_NOTES}" > "${notes_file}" - gh release create "${RELEASE_VERSION}" --title "${RELEASE_VERSION}" --notes-file "${notes_file}" --target "${MERGE_SHA}" + gh release create "${RELEASE_VERSION}" --title "${RELEASE_VERSION}" --notes-file "${notes_file}" --target "${RELEASE_COMMIT}" diff --git a/docs/releases.md b/docs/releases.md index 03b85e4..42a476e 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -2,6 +2,12 @@ `khoj-aio` uses upstream-version-plus-AIO-revision releases such as `2.0.0-beta.28-aio.1`. +## Version format + +- first wrapper release for upstream `2.0.0-beta.28`: `2.0.0-beta.28-aio.1` +- second wrapper-only release on the same upstream: `2.0.0-beta.28-aio.2` +- first wrapper release after upgrading upstream: `2.0.0-beta.29-aio.1` + ## Published image tags Every `main` build publishes: @@ -13,7 +19,8 @@ Every `main` build publishes: ## Release flow -1. Trigger **Release / Khoj-AIO** from `main`. +1. Trigger **Release / Khoj-AIO** from `main` with `action=prepare`. 2. The workflow computes the next `upstream-aio.N` version and opens a release PR. -3. Merge that PR into `main`. -4. After merge, the workflow creates the Git tag and GitHub Release automatically. +3. Review and merge that PR into `main`. +4. Trigger **Release / Khoj-AIO** from `main` again with `action=publish`. +5. The workflow reads the merged `CHANGELOG.md` entry, creates the Git tag, and publishes the GitHub Release.