Dependency Update Check #1
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: Dependency Update Check | |
| on: | |
| schedule: | |
| - cron: '0 6 * * 1' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| issues: write | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| check-updates: | |
| name: Check Ubuntu Package Updates | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| outputs: | |
| updates-available: ${{ steps.check.outputs.updates-available }} | |
| update-summary: ${{ steps.check.outputs.update-summary }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Build current image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| load: true | |
| tags: codeforge:current | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Check for package updates | |
| id: check | |
| run: | | |
| UPDATES=$(docker run --rm codeforge:current bash -c ' | |
| apt-get update -qq 2>/dev/null | |
| apt-get upgrade -s 2>/dev/null | grep "^Inst " || true | |
| ') | |
| COUNT=$(echo "$UPDATES" | grep -c "^Inst " || true) | |
| echo "updates-available=$([ "$COUNT" -gt 0 ] && echo "true" || echo "false")" >> $GITHUB_OUTPUT | |
| if [ "$COUNT" -gt 0 ]; then | |
| SUMMARY=$(echo "$UPDATES" | head -20 | awk '{print $2}') | |
| echo "update-summary<<EOF" >> $GITHUB_OUTPUT | |
| echo "**$COUNT packages** have updates available:" >> $GITHUB_OUTPUT | |
| echo "" >> $GITHUB_OUTPUT | |
| echo '```' >> $GITHUB_OUTPUT | |
| echo "$SUMMARY" >> $GITHUB_OUTPUT | |
| if [ "$COUNT" -gt 20 ]; then | |
| echo "... and $((COUNT - 20)) more" >> $GITHUB_OUTPUT | |
| fi | |
| echo '```' >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| echo "::warning::$COUNT package updates available" | |
| else | |
| echo "update-summary=All packages are up to date" >> $GITHUB_OUTPUT | |
| echo "::notice::All packages are up to date" | |
| fi | |
| - name: Scan current image | |
| uses: anchore/scan-action@v7 | |
| with: | |
| image: "codeforge:current" | |
| output-format: sarif | |
| output-file: grype-current.sarif | |
| severity-cutoff: high | |
| fail-build: false | |
| - name: Upload current scan results | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() | |
| with: | |
| sarif_file: grype-current.sarif | |
| category: dependency-check-current | |
| test-updated-image: | |
| name: Test Updated Image | |
| needs: check-updates | |
| if: needs.check-updates.outputs.updates-available == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Build image with updated packages | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| load: true | |
| tags: codeforge:updated | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-args: | | |
| UPGRADE_PACKAGES=true | |
| - name: Run Grype scan on updated image | |
| uses: anchore/scan-action@v7 | |
| with: | |
| image: "codeforge:updated" | |
| output-format: sarif | |
| output-file: grype-updated.sarif | |
| severity-cutoff: high | |
| fail-build: false | |
| - name: Upload updated scan results | |
| uses: github/codeql-action/upload-sarif@v4 | |
| if: always() | |
| with: | |
| sarif_file: grype-updated.sarif | |
| category: dependency-check-updated | |
| - name: Start services | |
| run: | | |
| sed -i '/build:/,/dockerfile: Dockerfile/c\ image: codeforge:updated' docker-compose.dev.yml | |
| sed -i 's/container_name: ai-dev/container_name: ci-test/' docker-compose.dev.yml | |
| docker compose -f docker-compose.dev.yml up -d | |
| echo "Waiting for services..." | |
| sleep 30 | |
| - name: Run integration tests | |
| run: | | |
| chmod +x test/run-tests.sh | |
| ./test/run-tests.sh ci-test | |
| - name: Cleanup | |
| if: always() | |
| run: docker compose -f docker-compose.dev.yml down -v --remove-orphans || true | |
| create-update-issue: | |
| name: Create Update Issue | |
| needs: [check-updates, test-updated-image] | |
| if: | | |
| always() && | |
| needs.check-updates.outputs.updates-available == 'true' && | |
| (needs.test-updated-image.result == 'success' || needs.test-updated-image.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check for existing issue | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const issues = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'dependencies' | |
| }); | |
| const existingIssue = issues.data.find(issue => | |
| issue.title.includes('Ubuntu package updates available') | |
| ); | |
| if (!existingIssue) { | |
| const summary = `${{ needs.check-updates.outputs.update-summary }}`; | |
| const testResult = `${{ needs.test-updated-image.result }}`; | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: 'Ubuntu package updates available', | |
| body: ` | |
| ## Package Updates Available | |
| ${summary} | |
| ## Compatibility Test | |
| ${testResult === 'success' ? 'Updated image passes all integration tests' : 'Updated image test was not run or failed'} | |
| ## Actions | |
| - [ ] Rebuild Docker image to pull latest packages | |
| - [ ] Verify Grype scan shows reduced vulnerabilities | |
| - [ ] Push updated image if all checks pass | |
| `, | |
| labels: ['dependencies', 'automated'] | |
| }); | |
| } |