Build ROOT Images #10
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: Build ROOT Images | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "Discover and update metadata without pushing images or committing README changes" | |
| required: false | |
| type: boolean | |
| default: false | |
| force_rebuild: | |
| description: "Rebuild release images even when the GHCR tag already exists" | |
| required: false | |
| type: boolean | |
| default: false | |
| schedule: | |
| - cron: "37 2 * * *" | |
| pull_request: | |
| paths: | |
| - ".github/workflows/images.yml" | |
| - "README.md" | |
| - "scripts/**" | |
| - "tests/**" | |
| permissions: | |
| contents: read | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAMESPACE: root-project | |
| IMAGE_NAME: root | |
| jobs: | |
| validate: | |
| name: Validate automation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Run actionlint | |
| uses: rhysd/actionlint@v1.7.12 | |
| - name: Run unit tests | |
| run: python -m unittest discover -s tests -v | |
| discover: | |
| name: Discover images | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| permissions: | |
| contents: read | |
| packages: read | |
| outputs: | |
| release_matrix: ${{ steps.plan.outputs.release_matrix }} | |
| release_count: ${{ steps.plan.outputs.release_count }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GHCR | |
| if: ${{ github.event_name != 'pull_request' && inputs.dry_run != true && github.ref_name == github.event.repository.default_branch }} | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Discover release matrix | |
| id: plan | |
| env: | |
| IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }} | |
| run: | | |
| args=(--image "$IMAGE" --plan-json build-plan.json --github-output "$GITHUB_OUTPUT") | |
| if [[ "${{ github.event_name }}" != "pull_request" && "${{ inputs.dry_run }}" != "true" && "${{ inputs.force_rebuild }}" != "true" && "${{ github.ref_name }}" == "${{ github.event.repository.default_branch }}" ]]; then | |
| args+=(--skip-existing) | |
| fi | |
| python scripts/root_images.py plan "${args[@]}" | |
| - name: Print discovery summary | |
| run: | | |
| python - <<'PY' | |
| import json | |
| from pathlib import Path | |
| plan = json.loads(Path("build-plan.json").read_text()) | |
| print(f"Image: {plan['image']}") | |
| print(f"Release images to build: {len(plan['release_images'])}") | |
| PY | |
| build-release: | |
| name: Build release image | |
| runs-on: ubuntu-latest | |
| needs: discover | |
| if: ${{ github.event_name != 'pull_request' && inputs.dry_run != true && github.ref_name == github.event.repository.default_branch && needs.discover.outputs.release_count != '0' }} | |
| timeout-minutes: 120 | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 3 | |
| matrix: ${{ fromJSON(needs.discover.outputs.release_matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push release image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: ${{ matrix.context }} | |
| file: ${{ matrix.dockerfile }} | |
| pull: true | |
| push: true | |
| tags: ${{ join(matrix.tags, ',') }} | |
| build-args: ${{ join(matrix.build_args, ',') }} | |
| labels: | | |
| org.opencontainers.image.source=https://github.com/${{ github.repository }} | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| org.opencontainers.image.version=${{ matrix.root_version }} | |
| - name: Smoke test release image | |
| run: docker run --rm "${{ matrix.primary_tag }}" root-config --version | |
| publish-metadata: | |
| name: Publish README metadata | |
| runs-on: ubuntu-latest | |
| needs: | |
| - discover | |
| - build-release | |
| if: >- | |
| ${{ | |
| always() && | |
| github.event_name != 'pull_request' && | |
| inputs.dry_run != true && | |
| github.ref_name == github.event.repository.default_branch && | |
| needs.discover.result == 'success' && | |
| (needs.build-release.result == 'success' || needs.build-release.result == 'skipped') | |
| }} | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.ref_name }} | |
| - name: Regenerate README image metadata | |
| id: plan | |
| env: | |
| IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }} | |
| run: | | |
| python scripts/root_images.py plan \ | |
| --image "$IMAGE" \ | |
| --plan-json build-plan.json | |
| python scripts/root_images.py update-readme --plan-json build-plan.json | |
| - name: Commit README update | |
| run: | | |
| if git diff --quiet README.md; then | |
| echo "README image metadata is already up to date" | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add README.md | |
| git commit -m "Update ROOT image metadata" | |
| git push |