Update Agent Versions #360
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
| name: Update Agent Versions | |
| on: | |
| schedule: | |
| # Run hourly at minute 0 | |
| - cron: '0 * * * *' | |
| workflow_dispatch: | |
| inputs: | |
| apply: | |
| description: 'Apply updates and commit to main' | |
| required: false | |
| default: 'true' | |
| type: boolean | |
| agents: | |
| description: 'Comma-separated agent IDs (leave empty for all)' | |
| required: false | |
| default: '' | |
| type: string | |
| permissions: | |
| contents: write | |
| issues: write | |
| jobs: | |
| check-versions: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| has_updates: ${{ steps.check.outputs.has_updates }} | |
| updates_json: ${{ steps.check.outputs.updates_json }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Check for version updates | |
| id: check | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set +e | |
| ARGS="--json" | |
| if [ -n "${{ inputs.agents }}" ]; then | |
| ARGS="$ARGS --agents ${{ inputs.agents }}" | |
| fi | |
| OUTPUT=$(python .github/workflows/update_versions.py $ARGS) | |
| EXIT_CODE=$? | |
| echo "$OUTPUT" | |
| # Save JSON output | |
| echo "updates_json<<EOF" >> $GITHUB_OUTPUT | |
| echo "$OUTPUT" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| # Check if updates are available (exit code 2) | |
| if [ $EXIT_CODE -eq 2 ]; then | |
| echo "has_updates=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_updates=false" >> $GITHUB_OUTPUT | |
| fi | |
| # Fail on actual errors (exit code 1) | |
| if [ $EXIT_CODE -eq 1 ]; then | |
| exit 1 | |
| fi | |
| notify-failure: | |
| needs: check-versions | |
| if: failure() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Create failure issue | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const title = `Version check failed - ${new Date().toISOString().split('T')[0]}`; | |
| const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; | |
| // Check if issue already exists today | |
| const existingIssues = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'version-check-failure', | |
| per_page: 10 | |
| }); | |
| const todayIssue = existingIssues.data.find(i => i.title === title); | |
| if (todayIssue) { | |
| // Add comment to existing issue | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: todayIssue.number, | |
| body: `Another failure occurred.\n\n**Run:** ${runUrl}` | |
| }); | |
| } else { | |
| // Create new issue | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: title, | |
| body: `The automated version check workflow failed.\n\n**Run:** ${runUrl}\n\nPlease investigate the failure.`, | |
| labels: ['version-check-failure', 'automated'] | |
| }); | |
| } | |
| apply-updates: | |
| needs: check-versions | |
| if: needs.check-versions.outputs.has_updates == 'true' && (github.event_name == 'schedule' || inputs.apply == true || inputs.apply == 'true') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Apply version updates | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| ARGS="--apply" | |
| if [ -n "${{ inputs.agents }}" ]; then | |
| ARGS="$ARGS --agents ${{ inputs.agents }}" | |
| fi | |
| python .github/workflows/update_versions.py $ARGS | |
| - name: Validate registry build | |
| run: | | |
| pip install jsonschema | |
| SKIP_URL_VALIDATION=1 python .github/workflows/build_registry.py | |
| - name: Verify agent auth support | |
| timeout-minutes: 15 | |
| run: python3 .github/workflows/verify_agents.py --auth-check | |
| - name: Generate commit message | |
| id: commit_msg | |
| run: | | |
| UPDATES='${{ needs.check-versions.outputs.updates_json }}' | |
| # Generate summary of updates | |
| SUMMARY=$(echo "$UPDATES" | python3 -c " | |
| import sys, json | |
| data = json.load(sys.stdin) | |
| updates = data.get('updates', []) | |
| if len(updates) == 1: | |
| u = updates[0] | |
| print(f\"Update {u['agent_id']} to {u['latest_version']}\") | |
| else: | |
| print(f\"Update {len(updates)} agents to latest versions\") | |
| ") | |
| # Generate details | |
| DETAILS=$(echo "$UPDATES" | python3 -c " | |
| import sys, json | |
| data = json.load(sys.stdin) | |
| for u in data.get('updates', []): | |
| print(f\"- {u['agent_id']}: {u['current_version']} -> {u['latest_version']}\") | |
| ") | |
| echo "summary=$SUMMARY" >> $GITHUB_OUTPUT | |
| echo "details<<EOF" >> $GITHUB_OUTPUT | |
| echo "$DETAILS" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: Commit and push to main | |
| env: | |
| COMMIT_SUMMARY: ${{ steps.commit_msg.outputs.summary }} | |
| COMMIT_DETAILS: ${{ steps.commit_msg.outputs.details }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add -A | |
| git commit -m "$(cat <<EOF | |
| $COMMIT_SUMMARY | |
| $COMMIT_DETAILS | |
| EOF | |
| )" | |
| git push origin main | |
| notify-apply-failure: | |
| needs: [check-versions, apply-updates] | |
| if: always() && needs.apply-updates.result == 'failure' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Create failure issue | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const title = `Version update failed - ${new Date().toISOString().split('T')[0]}`; | |
| const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; | |
| // Check if issue already exists today | |
| const existingIssues = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'version-update-failure', | |
| per_page: 10 | |
| }); | |
| const todayIssue = existingIssues.data.find(i => i.title === title); | |
| if (todayIssue) { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: todayIssue.number, | |
| body: `Another failure occurred.\n\n**Run:** ${runUrl}` | |
| }); | |
| } else { | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: title, | |
| body: `The automated version update workflow failed while applying updates.\n\n**Run:** ${runUrl}\n\nThis could be due to:\n- Registry validation failure\n- Auth verification failure\n- Git push conflict\n- Network issues\n\nPlease investigate.`, | |
| labels: ['version-update-failure', 'automated'] | |
| }); | |
| } |