mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-07-05 15:10:16 +02:00
ci: optimise build pipeline — shared dev image build and skip tests on tag push (#167)
* ci: split dev image build into a shared job Extract the Docker build step into a dedicated `build` job so `quality` and `tests` no longer each build the image independently. Both jobs now load from the shared `devbuild` GHA cache scope and declare `needs: build`. * ci: skip quality+tests on tag push, verify prior CI run instead When tagging a commit that already passed CI on main, there is no need to run quality and tests again. Both jobs now skip for tag refs. A new `verify-prior-run` job runs instead: it queries the GitHub API for a prior successful CI run on the same SHA (excluding the current run) and fails fast if none is found, preventing deployment of untested tags. `build-deploy` now uses `always() && !cancelled() && !failure()` so it handles the mix of skipped (quality/tests) and successful (verify-prior-run) needed jobs correctly. * ci: bump GitHub Actions to Node.js 24 compatible versions * ci: add Dependabot config for GitHub Actions version updates * ci: pin all GitHub Actions to commit SHAs * ci: disable credential persistence on all checkout steps
This commit is contained in:
@@ -28,3 +28,7 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
|||||||
+79
-27
@@ -17,31 +17,57 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
quality:
|
build:
|
||||||
name: Code Quality
|
name: Build Dev Image
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 15
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
- name: Lint Dockerfile
|
- name: Lint Dockerfile
|
||||||
uses: hadolint/hadolint-action@v3.1.0
|
uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- name: Build Docker images
|
- name: Build Docker images
|
||||||
uses: docker/bake-action@v5
|
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7
|
||||||
with:
|
with:
|
||||||
pull: true
|
pull: true
|
||||||
|
files: |
|
||||||
|
compose.yaml
|
||||||
|
compose.override.yaml
|
||||||
|
set: |
|
||||||
|
*.cache-from=type=gha,scope=${{github.ref}}-devbuild
|
||||||
|
*.cache-from=type=gha,scope=refs/heads/main-devbuild
|
||||||
|
*.cache-to=type=gha,scope=${{github.ref}}-devbuild,mode=${{ github.event_name == 'pull_request' && 'min' || 'max' }}
|
||||||
|
|
||||||
|
quality:
|
||||||
|
name: Code Quality
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 20
|
||||||
|
needs: build
|
||||||
|
if: "!startsWith(github.ref, 'refs/tags/')"
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
|
- name: Load Docker images
|
||||||
|
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7
|
||||||
|
with:
|
||||||
load: true
|
load: true
|
||||||
files: |
|
files: |
|
||||||
compose.yaml
|
compose.yaml
|
||||||
compose.override.yaml
|
compose.override.yaml
|
||||||
set: |
|
set: |
|
||||||
*.cache-from=type=gha,scope=${{github.ref}}-quality
|
*.cache-from=type=gha,scope=${{github.ref}}-devbuild
|
||||||
*.cache-from=type=gha,scope=refs/heads/main
|
|
||||||
*.cache-to=type=gha,scope=${{github.ref}}-quality,mode=${{ github.event_name == 'pull_request' && 'min' || 'max' }}
|
|
||||||
- name: Start services
|
- name: Start services
|
||||||
run: docker compose up php database --wait --no-build
|
run: docker compose up php database --wait --no-build
|
||||||
- name: Warm up dev cache
|
- name: Warm up dev cache
|
||||||
@@ -78,27 +104,28 @@ jobs:
|
|||||||
name: Tests
|
name: Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
|
needs: build
|
||||||
|
if: "!startsWith(github.ref, 'refs/tags/')"
|
||||||
permissions:
|
permissions:
|
||||||
checks: write
|
checks: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
- name: Set up Docker Buildx
|
with:
|
||||||
uses: docker/setup-buildx-action@v3
|
persist-credentials: false
|
||||||
- name: Build Docker images
|
- name: Set up Docker Buildx
|
||||||
uses: docker/bake-action@v5
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
|
- name: Load Docker images
|
||||||
|
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7
|
||||||
with:
|
with:
|
||||||
pull: true
|
|
||||||
load: true
|
load: true
|
||||||
files: |
|
files: |
|
||||||
compose.yaml
|
compose.yaml
|
||||||
compose.override.yaml
|
compose.override.yaml
|
||||||
set: |
|
set: |
|
||||||
*.cache-from=type=gha,scope=${{github.ref}}-tests
|
*.cache-from=type=gha,scope=${{github.ref}}-devbuild
|
||||||
*.cache-from=type=gha,scope=refs/heads/main
|
|
||||||
*.cache-to=type=gha,scope=${{github.ref}}-tests,mode=${{ github.event_name == 'pull_request' && 'min' || 'max' }}
|
|
||||||
- name: Start services
|
- name: Start services
|
||||||
run: docker compose up php database --wait --no-build
|
run: docker compose up php database --wait --no-build
|
||||||
- name: Create test database
|
- name: Create test database
|
||||||
@@ -111,13 +138,34 @@ jobs:
|
|||||||
run: docker compose exec -T php vendor/bin/phpunit --log-junit var/phpunit/junit.xml
|
run: docker compose exec -T php vendor/bin/phpunit --log-junit var/phpunit/junit.xml
|
||||||
- name: Publish PHPUnit test results
|
- name: Publish PHPUnit test results
|
||||||
if: always()
|
if: always()
|
||||||
uses: mikepenz/action-junit-report@v5
|
uses: mikepenz/action-junit-report@d9f48fc87bc235f7e214acf696ca5abc0a986f16 # v6
|
||||||
with:
|
with:
|
||||||
report_paths: var/phpunit/junit.xml
|
report_paths: var/phpunit/junit.xml
|
||||||
check_name: PHPUnit
|
check_name: PHPUnit
|
||||||
- name: Doctrine Schema Validator
|
- name: Doctrine Schema Validator
|
||||||
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
|
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
|
||||||
|
|
||||||
|
verify-prior-run:
|
||||||
|
name: Verify Prior CI Run
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
steps:
|
||||||
|
- name: Check for successful CI run on this commit
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
count=$(gh api \
|
||||||
|
"repos/${{ github.repository }}/actions/workflows/ci.yml/runs?head_sha=${{ github.sha }}&status=success&per_page=5" \
|
||||||
|
--jq "[.workflow_runs[] | select(.id != ${{ github.run_id }})] | length")
|
||||||
|
if [[ "$count" -eq 0 ]]; then
|
||||||
|
echo "::error::No prior successful CI run found for ${{ github.sha }}. Only tag commits that have passed CI on main."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Found $count prior successful CI run(s) for this commit."
|
||||||
|
|
||||||
build-deploy:
|
build-deploy:
|
||||||
name: Build and Deploy
|
name: Build and Deploy
|
||||||
permissions:
|
permissions:
|
||||||
@@ -126,17 +174,21 @@ jobs:
|
|||||||
environment:
|
environment:
|
||||||
name: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || 'acceptance' }}
|
name: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || 'acceptance' }}
|
||||||
url: ${{ vars.URL }}
|
url: ${{ vars.URL }}
|
||||||
needs: [quality, tests]
|
needs: [quality, tests, verify-prior-run]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
if: (github.ref == 'refs/heads/main' && false) || startsWith(github.ref, 'refs/tags/')
|
if: >-
|
||||||
|
always() && !cancelled() && !failure() &&
|
||||||
|
((github.ref == 'refs/heads/main' && false) || startsWith(github.ref, 'refs/tags/'))
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||||
- name: Log in to GitHub Container Registry
|
- name: Log in to GitHub Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@c99871dec2022cc055c062a10cc1a1310835ceb4 # v4
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -164,7 +216,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Build and Push Docker images
|
- name: Build and Push Docker images
|
||||||
uses: docker/bake-action@v5
|
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7
|
||||||
with:
|
with:
|
||||||
pull: true
|
pull: true
|
||||||
push: true
|
push: true
|
||||||
@@ -178,7 +230,7 @@ jobs:
|
|||||||
*.tags=${{ steps.meta.outputs.full_name }}
|
*.tags=${{ steps.meta.outputs.full_name }}
|
||||||
|
|
||||||
- name: Create Sentry release
|
- name: Create Sentry release
|
||||||
uses: getsentry/action-release@v3
|
uses: getsentry/action-release@ff07929a6537bac57790c3451cf4d364aca38528 # v3
|
||||||
env:
|
env:
|
||||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||||
|
|||||||
Reference in New Issue
Block a user