1name: Pipeline
2
3on:
4 pull_request:
5 push:
6 branches: [main]
7 tags: ['v*.*.*']
8
9permissions:
10 contents: read
11
12concurrency:
13 group: ${{ github.workflow }}-${{ github.ref }}
14 cancel-in-progress: ${{ github.event_name == 'pull_request' }}
15
16jobs:
17 test:
18 runs-on: ubuntu-latest
19 timeout-minutes: 20
20 services:
21 postgres:
22 image: postgres:17
23 env: { POSTGRES_PASSWORD: test, POSTGRES_DB: app }
24 ports: ['5432:5432']
25 options: --health-cmd "pg_isready -U postgres" --health-interval 5s --health-retries 10
26 steps:
27 - uses: actions/checkout@v7
28 - uses: actions/setup-java@v6
29 with: { distribution: temurin, java-version: '25', cache: maven }
30 - run: mvn -B verify
31 - uses: actions/upload-artifact@v7
32 if: always()
33 with: { name: test-reports, path: target/surefire-reports, retention-days: 7 }
34
35 image:
36 needs: test
37 if: github.event_name == 'push' # not on PRs
38 runs-on: ubuntu-latest
39 permissions: { contents: read, packages: write }
40 outputs:
41 tag: ${{ steps.vars.outputs.tag }}
42 steps:
43 - uses: actions/checkout@v7
44 - id: vars # tag to deploy
45 run: |
46 if [[ "$GITHUB_REF_TYPE" == tag ]]; then echo "tag=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT";
47 else echo "tag=sha-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"; fi
48 - uses: docker/login-action@v4
49 with: { registry: ghcr.io, username: '${{ github.actor }}', password: '${{ secrets.GITHUB_TOKEN }}' }
50 - id: meta
51 uses: docker/metadata-action@v6
52 with:
53 images: ghcr.io/${{ github.repository }}
54 tags: |
55 type=ref,event=branch
56 type=sha
57 type=semver,pattern={{version}}
58 type=semver,pattern={{major}}.{{minor}}
59 - uses: docker/setup-buildx-action@v4
60 - uses: docker/build-push-action@v7
61 with:
62 context: .
63 push: true
64 tags: ${{ steps.meta.outputs.tags }}
65 labels: ${{ steps.meta.outputs.labels }}
66 cache-from: type=gha
67 cache-to: type=gha,mode=max
68
69 deploy-staging:
70 needs: image
71 if: github.ref == 'refs/heads/main'
72 uses: ./.github/workflows/deploy.yml # reusable deploy (workflow_call)
73 with: { environment: staging, tag: '${{ needs.image.outputs.tag }}' }
74 secrets: inherit
75 permissions: { id-token: write, contents: read }
76
77 deploy-production:
78 needs: image
79 if: startsWith(github.ref, 'refs/tags/v')
80 uses: ./.github/workflows/deploy.yml # production env requires approval
81 with: { environment: production, tag: '${{ needs.image.outputs.tag }}' }
82 secrets: inherit
83 permissions: { id-token: write, contents: read }