diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index b316f0f..cc4b637 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -213,11 +213,12 @@ jobs: } >> "$GITHUB_OUTPUT" - name: Commit prepared CHANGELOG to dev via API - uses: vig-os/commit-action@c0024cbad0e501764127cccab732c6cd465b4646 # v0.1.5 + uses: vig-os/commit-action@1bc004353d08d9332a0cb54920b148256220c8e0 # v0.2.0 env: GH_TOKEN: ${{ steps.commit_app_token.outputs.token }} GITHUB_REPOSITORY: ${{ github.repository }} TARGET_BRANCH: refs/heads/dev + MAX_ATTEMPTS: "3" COMMIT_MESSAGE: |- chore: freeze changelog for release ${{ needs.validate.outputs.version }} @@ -263,11 +264,12 @@ jobs: " - name: Commit stripped CHANGELOG to release branch via API - uses: vig-os/commit-action@c0024cbad0e501764127cccab732c6cd465b4646 # v0.1.5 + uses: vig-os/commit-action@1bc004353d08d9332a0cb54920b148256220c8e0 # v0.2.0 env: GH_TOKEN: ${{ steps.commit_app_token.outputs.token }} GITHUB_REPOSITORY: ${{ github.repository }} TARGET_BRANCH: refs/heads/${{ needs.validate.outputs.release_branch }} + MAX_ATTEMPTS: "3" COMMIT_MESSAGE: |- chore: prepare release ${{ needs.validate.outputs.version }} @@ -348,11 +350,12 @@ jobs: - name: Commit CHANGELOG rollback to dev via API if: ${{ failure() && steps.rollback_prepare.outputs.changelog_rollback_needed == 'true' }} - uses: vig-os/commit-action@c0024cbad0e501764127cccab732c6cd465b4646 # v0.1.5 + uses: vig-os/commit-action@1bc004353d08d9332a0cb54920b148256220c8e0 # v0.2.0 env: GH_TOKEN: ${{ steps.commit_app_token.outputs.token }} GITHUB_REPOSITORY: ${{ github.repository }} TARGET_BRANCH: refs/heads/dev + MAX_ATTEMPTS: "3" COMMIT_MESSAGE: |- chore: rollback failed prepare-release ${{ needs.validate.outputs.version }} diff --git a/.github/workflows/release-core.yml b/.github/workflows/release-core.yml index 7642893..61021e6 100644 --- a/.github/workflows/release-core.yml +++ b/.github/workflows/release-core.yml @@ -162,19 +162,6 @@ jobs: - name: Fix git safe.directory run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - - name: Validate image accessibility - env: - IMAGE_TAG: ${{ needs.resolve-image.outputs.image-tag }} - run: | - set -euo pipefail - IMAGE="ghcr.io/vig-os/devcontainer:${IMAGE_TAG}" - echo "Validating image availability: $IMAGE" - if ! retry --retries 3 --backoff 5 --max-backoff 30 -- docker manifest inspect "$IMAGE" > /dev/null 2>&1; then - echo "ERROR: Cannot access image manifest: $IMAGE" - echo "Check whether the tag exists and whether this workflow has access to GHCR." - exit 1 - fi - - name: Record pre-finalization SHA id: pre_sha run: | @@ -274,7 +261,20 @@ jobs: echo "ERROR: PR #$PR_NUMBER is still in draft" exit 1 fi - if [ "$REVIEW_DECISION" != "APPROVED" ]; then + if [ "$REVIEW_DECISION" = "APPROVED" ]; then + echo "PR #$PR_NUMBER is approved" + elif [ "$REVIEW_DECISION" = "null" ] || [ -z "$REVIEW_DECISION" ]; then + # Bot approval fallback when gh pr list leaves reviewDecision empty (#438) + APPROVED_COUNT=$(retry --retries 3 --backoff 5 --max-backoff 30 -- gh api \ + --paginate --slurp \ + "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ + | jq 'add | map(select(.state == "APPROVED")) | length') + if [ "$APPROVED_COUNT" -eq 0 ]; then + echo "ERROR: PR #$PR_NUMBER is not approved (reviewDecision: $REVIEW_DECISION, approved reviews: 0)" + exit 1 + fi + echo "reviewDecision='$REVIEW_DECISION' but $APPROVED_COUNT approved review(s) found" + else echo "ERROR: PR #$PR_NUMBER is not approved (status: $REVIEW_DECISION)" exit 1 fi @@ -379,11 +379,12 @@ jobs: - name: Commit and push finalization changes via API if: ${{ inputs.release_kind == 'final' }} - uses: vig-os/commit-action@c0024cbad0e501764127cccab732c6cd465b4646 # v0.1.5 + uses: vig-os/commit-action@1bc004353d08d9332a0cb54920b148256220c8e0 # v0.2.0 env: GH_TOKEN: ${{ steps.commit_app_token.outputs.token }} GITHUB_REPOSITORY: ${{ github.repository }} TARGET_BRANCH: refs/heads/release/${{ needs.validate.outputs.version }} + MAX_ATTEMPTS: "3" COMMIT_MESSAGE: |- chore: finalize release ${{ needs.validate.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2bb29a..e54c182 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -194,6 +194,7 @@ jobs: VERSION: ${{ needs.core.outputs.version }} PR_NUMBER: ${{ needs.core.outputs.pr_number }} GH_TOKEN: ${{ steps.release_app_token.outputs.token }} + GH_REPO: ${{ github.repository }} run: | set -euo pipefail WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" diff --git a/.github/workflows/repository-dispatch.yml b/.github/workflows/repository-dispatch.yml index b9daecd..141df91 100644 --- a/.github/workflows/repository-dispatch.yml +++ b/.github/workflows/repository-dispatch.yml @@ -268,6 +268,7 @@ jobs: GH_TOKEN: ${{ steps.generate_commit_token.outputs.token }} GITHUB_REPOSITORY: ${{ github.repository }} TARGET_BRANCH: refs/heads/${{ steps.prepare_branch.outputs.branch_name }} + MAX_ATTEMPTS: "3" ALLOW_EMPTY: "true" COMMIT_MESSAGE: |- chore: deploy ${{ needs.validate.outputs.tag }} diff --git a/.github/workflows/sync-issues.yml b/.github/workflows/sync-issues.yml index f71e8fd..9243099 100644 --- a/.github/workflows/sync-issues.yml +++ b/.github/workflows/sync-issues.yml @@ -135,12 +135,13 @@ jobs: - name: Commit and push changes via API id: commit if: steps.sync.outputs.modified-files != '' - uses: vig-os/commit-action@c0024cbad0e501764127cccab732c6cd465b4646 # v0.1.5 + uses: vig-os/commit-action@1bc004353d08d9332a0cb54920b148256220c8e0 # v0.2.0 env: # Use App token so push can bypass branch protection when App is in bypass list GH_TOKEN: ${{ steps.generate-token.outputs.token }} GITHUB_REPOSITORY: ${{ github.repository }} TARGET_BRANCH: refs/heads/${{ github.event.inputs.target-branch || 'dev' }} + MAX_ATTEMPTS: "3" COMMIT_MESSAGE: "${{ github.event.inputs.commit-msg || 'chore: sync issues and PRs' }}" FILE_PATHS: ${{ steps.sync.outputs.modified-files }}