-
-
Notifications
You must be signed in to change notification settings - Fork 31
fix: make release workflow resilient to re-runs [skip changelog] #577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
482b09d
0e3e5f1
2a6e9bd
a7d05ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -246,35 +246,63 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SCRIPT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chmod +x /tmp/wait-for-crate.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Create idempotent publish helper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cat > /tmp/publish-crate.sh << 'SCRIPT' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ $# -ne 2 ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: $0 <crate> <version>" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| crate="$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version="$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Publishing $crate $version..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cargo publish -p "$crate" 2>&1; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$crate $version published successfully" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check crates.io API for the specific version (handles older tags, indexing lag) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status=$(curl -s -o /dev/null -w "%{http_code}" "https://crates.io/api/v1/crates/$crate/$version") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$status" = "200" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$crate $version already published, skipping" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Publish failed and $crate $version not found on crates.io (HTTP $status)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SCRIPT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chmod +x /tmp/publish-crate.sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Publish order: agnix-rules (leaf) -> agnix-core -> agnix-cli/agnix-lsp/agnix-mcp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish agnix-rules | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: cargo publish -p agnix-rules | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/publish-crate.sh agnix-rules ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Wait for agnix-rules indexing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/wait-for-crate.sh agnix-rules ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish agnix-core | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: cargo publish -p agnix-core | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/publish-crate.sh agnix-core ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Wait for agnix-core indexing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/wait-for-crate.sh agnix-core ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish agnix-cli | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: cargo publish -p agnix-cli | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/publish-crate.sh agnix-cli ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish agnix-lsp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: cargo publish -p agnix-lsp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/publish-crate.sh agnix-lsp ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish agnix-mcp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: cargo publish -p agnix-mcp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: /tmp/publish-crate.sh agnix-mcp ${{ steps.version.outputs.version }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -444,6 +472,8 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: npm --prefix website run version:cut -- "${{ steps.version.outputs.version }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Commit and push versioned docs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.COMMITTER_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git config user.name "github-actions[bot]" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -452,6 +482,19 @@ jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if git diff --cached --quiet; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "No changes to commit" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BRANCH="docs/version-${{ steps.version.outputs.version }}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git checkout -B "$BRANCH" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git commit -m "docs: version ${{ steps.version.outputs.version }} docs and update site data" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| git commit -m "docs: version ${{ steps.version.outputs.version }} docs and update site data" | |
| git commit -m "docs: version ${{ steps.version.outputs.version }} docs and update site data" | |
| # Intentionally force-push to update the auto-generated docs branch on workflow re-runs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment explaining force-push is intentional for re-runs of the auto-generated docs branch.
Copilot
AI
Feb 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR body on line 497 could be more informative by mentioning that it includes rule docs regeneration and site data updates (as evidenced by the files added on line 481). This would help reviewers understand the full scope of changes.
Consider: "Auto-generated versioned docs snapshot for v${{ steps.version.outputs.version }}, including updated rule docs and site data."
| --body "Auto-generated versioned docs snapshot for v${{ steps.version.outputs.version }}." \ | |
| --body "Auto-generated versioned docs snapshot for v${{ steps.version.outputs.version }}, including updated rule docs and site data." \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to mention rule docs and site data updates.
Copilot
AI
Feb 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR existence check on line 490 suppresses all errors with 2>/dev/null, which means network failures or API errors will be treated the same as "PR doesn't exist" and will attempt to create a duplicate PR. While gh pr create will likely fail in those cases, it's more robust to check the exit code and stderr explicitly.
Consider: if gh pr view --head "$BRANCH" --json number --jq '.number' >/dev/null 2>&1; then
Or add error handling to distinguish between "not found" and other errors.
| if gh pr view --head "$BRANCH" --json number --jq '.number' 2>/dev/null; then | |
| echo "PR already exists for $BRANCH, updated with force push" | |
| else | |
| gh pr create \ | |
| --base main \ | |
| --head "$BRANCH" \ | |
| --title "docs: version ${{ steps.version.outputs.version }} docs" \ | |
| --body "Auto-generated versioned docs snapshot for v${{ steps.version.outputs.version }}." \ | |
| --label "documentation" | |
| fi | |
| PR_CHECK_ERR="$(mktemp)" | |
| if gh pr view --head "$BRANCH" --json number --jq '.number' >/dev/null 2>"$PR_CHECK_ERR"; then | |
| echo "PR already exists for $BRANCH, updated with force push" | |
| else | |
| if grep -qiE 'not[[:space:]]+found|could not find pull request|no pull requests' "$PR_CHECK_ERR"; then | |
| gh pr create \ | |
| --base main \ | |
| --head "$BRANCH" \ | |
| --title "docs: version ${{ steps.version.outputs.version }} docs" \ | |
| --body "Auto-generated versioned docs snapshot for v${{ steps.version.outputs.version }}." \ | |
| --label "documentation" | |
| else | |
| echo "Error checking for existing PR for $BRANCH:" | |
| cat "$PR_CHECK_ERR" | |
| rm -f "$PR_CHECK_ERR" | |
| exit 1 | |
| fi | |
| fi | |
| rm -f "$PR_CHECK_ERR" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Now uses a temp file for stderr and distinguishes 'not found' from API errors before attempting PR creation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment on line 265 mentions "handles older tags, indexing lag", but this check is specifically for detecting if a crate version is already published. The comment is misleading because the check happens during a publish failure, not as a general check for existence.
Consider clarifying: "Check if crate version already exists on crates.io (handles re-runs after partial failures)"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Updated the comment to clarify it handles re-runs after partial failures.