Checkpoint Update #173
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Automated checkpoint updates. | |
| # | |
| # Triggered whenever the integration tests complete; requires both checkpoint artifacts. | |
| # Downloads checkpoint artifacts produced by generate-checkpoints-* jobs, | |
| # appends new entries to the checkpoint files, validates them, and opens a PR. | |
| # | |
| # The PR requires human review before merge; checkpoints are consensus-critical. | |
| name: Checkpoint Update | |
| on: | |
| # zizmor: ignore[dangerous-triggers] -- triggers only on internal CI workflow completion, | |
| # processes deterministic checkpoint data from artifacts, no untrusted user input | |
| workflow_run: | |
| workflows: ["Integration Tests on GCP"] | |
| types: [completed] | |
| branches: [main] | |
| # Manual trigger for testing; resolves the latest completed integration test run automatically | |
| workflow_dispatch: | |
| permissions: {} | |
| jobs: | |
| update-checkpoints: | |
| name: Update checkpoint files | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: read | |
| contents: read | |
| env: | |
| MAINNET_CHECKPOINTS: zebra-chain/src/parameters/checkpoint/main-checkpoints.txt | |
| TESTNET_CHECKPOINTS: zebra-chain/src/parameters/checkpoint/test-checkpoints.txt | |
| steps: | |
| - name: Generate release app token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 #v3.2.0 | |
| with: | |
| app-id: ${{ vars.RELEASE_APP_ID }} | |
| private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} | |
| permission-contents: write | |
| permission-pull-requests: write | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 | |
| with: | |
| persist-credentials: false | |
| ref: main | |
| token: ${{ steps.app-token.outputs.token }} | |
| # Resolve the integration test run ID. | |
| # For workflow_run: use the triggering run directly. | |
| # For workflow_dispatch: find the latest completed run via the API. | |
| - name: Resolve integration test run ID | |
| id: resolve-run | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| WF_RUN_ID: ${{ github.event.workflow_run.id }} | |
| WF_RUN_URL: ${{ github.event.workflow_run.html_url }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| if [ "$EVENT_NAME" = "workflow_run" ]; then | |
| RUN_ID="$WF_RUN_ID" | |
| RUN_URL="$WF_RUN_URL" | |
| else | |
| RUN_ID=$(gh run list \ | |
| --workflow "Integration Tests on GCP" \ | |
| --branch main \ | |
| --status completed \ | |
| --limit 1 \ | |
| --json databaseId \ | |
| --jq '.[0].databaseId') | |
| RUN_URL="https://github.com/${REPO}/actions/runs/${RUN_ID}" | |
| fi | |
| if [ -z "$RUN_ID" ]; then | |
| echo "No completed integration test run found" | |
| exit 1 | |
| fi | |
| echo "run_id=${RUN_ID}" >> "$GITHUB_OUTPUT" | |
| echo "run_url=${RUN_URL}" >> "$GITHUB_OUTPUT" | |
| echo "Using integration test run: ${RUN_URL}" | |
| # Download checkpoint artifacts from the integration test run. | |
| - name: Download mainnet checkpoint artifact | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1 | |
| with: | |
| name: generate-checkpoints-mainnet-checkpoints | |
| run-id: ${{ steps.resolve-run.outputs.run_id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Download testnet checkpoint artifact | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1 | |
| with: | |
| name: generate-checkpoints-testnet-checkpoints | |
| run-id: ${{ steps.resolve-run.outputs.run_id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify required checkpoint artifacts | |
| run: | | |
| for artifact in main-checkpoints.txt test-checkpoints.txt; do | |
| if [ ! -f "$artifact" ]; then | |
| echo "::error::Required checkpoint artifact file is missing: ${artifact}" | |
| exit 1 | |
| fi | |
| LINES=$(wc -l < "$artifact" | tr -d ' ') | |
| echo "${artifact}: ${LINES} checkpoint lines" | |
| done | |
| # Append new mainnet checkpoints (entries with heights higher than current last) | |
| - name: Append new mainnet checkpoints | |
| run: | | |
| CURRENT_LAST=$(tail -1 "${MAINNET_CHECKPOINTS}" | awk '{print $1}') | |
| echo "Current last mainnet checkpoint: ${CURRENT_LAST}" | |
| # Extract only new entries (height > current last) | |
| NEW_COUNT=$(awk -v last="$CURRENT_LAST" '$1 > last' main-checkpoints.txt | wc -l | tr -d ' ') | |
| echo "New mainnet checkpoints to append: ${NEW_COUNT}" | |
| if [ "$NEW_COUNT" -gt 0 ]; then | |
| awk -v last="$CURRENT_LAST" '$1 > last' main-checkpoints.txt >> "${MAINNET_CHECKPOINTS}" | |
| NEW_LAST=$(tail -1 "${MAINNET_CHECKPOINTS}" | awk '{print $1}') | |
| echo "Updated last mainnet checkpoint: ${NEW_LAST}" | |
| fi | |
| # Append new testnet checkpoints | |
| - name: Append new testnet checkpoints | |
| run: | | |
| CURRENT_LAST=$(tail -1 "${TESTNET_CHECKPOINTS}" | awk '{print $1}') | |
| echo "Current last testnet checkpoint: ${CURRENT_LAST}" | |
| NEW_COUNT=$(awk -v last="$CURRENT_LAST" '$1 > last' test-checkpoints.txt | wc -l | tr -d ' ') | |
| echo "New testnet checkpoints to append: ${NEW_COUNT}" | |
| if [ "$NEW_COUNT" -gt 0 ]; then | |
| awk -v last="$CURRENT_LAST" '$1 > last' test-checkpoints.txt >> "${TESTNET_CHECKPOINTS}" | |
| NEW_LAST=$(tail -1 "${TESTNET_CHECKPOINTS}" | awk '{print $1}') | |
| echo "Updated last testnet checkpoint: ${NEW_LAST}" | |
| fi | |
| # Validate the updated checkpoint files | |
| - name: Validate checkpoint files | |
| run: | | |
| .github/scripts/validate-checkpoints.sh "${MAINNET_CHECKPOINTS}" | |
| .github/scripts/validate-checkpoints.sh "${TESTNET_CHECKPOINTS}" | |
| # Check if there are actual changes to commit | |
| - name: Check for changes | |
| id: changes | |
| run: | | |
| if git diff --quiet; then | |
| echo "No changes to commit" | |
| echo "has_changes=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Changes detected:" | |
| git diff --stat | |
| echo "has_changes=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| # Open or update a PR with the checkpoint changes | |
| - name: Create checkpoint update PR | |
| if: steps.changes.outputs.has_changes == 'true' | |
| uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 #v8.1.1 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| branch: chore/update-checkpoints | |
| add-paths: | | |
| zebra-chain/src/parameters/checkpoint/main-checkpoints.txt | |
| zebra-chain/src/parameters/checkpoint/test-checkpoints.txt | |
| title: "chore(chain): update checkpoints" | |
| body: | | |
| Automated checkpoint update from the integration test run. | |
| **Source:** [Integration test run #${{ steps.resolve-run.outputs.run_id }}](${{ steps.resolve-run.outputs.run_url }}) | |
| Checkpoints are consensus-critical. Verify the new hashes against the source run before merging. | |
| labels: A-release,C-enhancement | |
| commit-message: "chore(chain): update checkpoints" | |
| delete-branch: true |