Build and deploy #3
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 and deploy | |
| concurrency: | |
| group: "${{ github.workflow }}-${{ github.ref }}-build-deploy" | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| on: | |
| workflow_call: | |
| workflow_dispatch: | |
| jobs: | |
| config: | |
| name: Detect changed apps | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| matrix: ${{ steps.changes.outputs.matrix }} | |
| has_changes: ${{ steps.changes.outputs.has_changes }} | |
| repository: ${{ steps.repository.outputs.repository }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| filter: "blob:none" | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v5 | |
| with: | |
| cache: true | |
| - name: Use node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24.x | |
| - name: Set lowercase repository name | |
| id: repository | |
| run: | |
| echo "repository=$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> | |
| $GITHUB_OUTPUT | |
| - name: Detect affected apps | |
| id: changes | |
| env: | |
| # @see {@link https://github.com/vercel/turborepo/issues/9320#issuecomment-2499219314} | |
| TURBO_SCM_BASE: | |
| ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || | |
| github.event.before }} | |
| ALL_APPS: | | |
| [ | |
| { | |
| "name": "knowledge-base", | |
| "image": "app", | |
| "environment": "production", | |
| "public_url": "${{ vars.NEXT_PUBLIC_APP_BASE_URL }}", | |
| "service_id": "${{ vars.APP_SERVICE_ID }}" | |
| }, | |
| { | |
| "name": "api", | |
| "image": "api", | |
| "environment": "production", | |
| "public_url": "${{ vars.K8S_SECRET_API_BASE_URL }}", | |
| "service_id": "${{ vars.API_SERVICE_ID }}" | |
| } | |
| ] | |
| run: | | |
| set -eux | |
| AFFECTED=$( | |
| pnpm dlx turbo ls --affected --output json \ | |
| 2>/dev/null || echo '{"packages":{"items":[]}}' | |
| ) | |
| NAMES=$(echo "$AFFECTED" | jq -c '[.packages.items[] | select(.path | startswith("apps/")) | .name | sub("^@dariah-eric/"; "")]') | |
| MATRIX=$(echo "$ALL_APPS" | jq -c --argjson names "$NAMES" '[.[] | select(.name as $n | $names | index($n))]') | |
| echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT" | |
| if [ "$MATRIX" = "[]" ]; then | |
| echo "has_changes=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has_changes=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| build: | |
| name: Build and push docker images | |
| needs: [config] | |
| if: needs.config.outputs.has_changes == 'true' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 60 | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| target: ${{ fromJSON(needs.config.outputs.matrix) }} | |
| max-parallel: 1 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Set up docker buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Sign in to the container registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: "ghcr.io" | |
| username: "${{ github.actor }}" | |
| password: "${{ secrets.GITHUB_TOKEN }}" | |
| - name: Extract metadata (tags, labels) for docker image | |
| id: meta | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: "ghcr.io/${{ needs.config.outputs.repository }}-${{ matrix.target.image }}" | |
| tags: | | |
| type=raw,value={{sha}} | |
| type=ref,event=branch | |
| - name: Build and push docker image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| target: "${{ matrix.target.image }}" | |
| push: true | |
| tags: "${{ steps.meta.outputs.tags }}" | |
| labels: "${{ steps.meta.outputs.labels }}" | |
| build-args: | | |
| "NEXT_PUBLIC_APP_BASE_URL=${{ vars.NEXT_PUBLIC_APP_BASE_URL }}" | |
| "NEXT_PUBLIC_APP_BOTS=disabled" | |
| "NEXT_PUBLIC_APP_GOOGLE_SITE_VERIFICATION=${{ vars.NEXT_PUBLIC_APP_GOOGLE_SITE_VERIFICATION }}" | |
| "NEXT_PUBLIC_APP_IMPRINT_CUSTOM_CONFIG=disabled" | |
| "NEXT_PUBLIC_APP_IMPRINT_SERVICE_BASE_URL=${{ vars.NEXT_PUBLIC_IMPRINT_SERVICE_BASE_URL }}" | |
| "NEXT_PUBLIC_APP_MATOMO_BASE_URL=${{ vars.NEXT_PUBLIC_MATOMO_BASE_URL }}" | |
| "NEXT_PUBLIC_APP_MATOMO_ID=${{ vars.NEXT_PUBLIC_APP_MATOMO_ID }}" | |
| "NEXT_PUBLIC_APP_SENTRY_DSN=${{ vars.NEXT_PUBLIC_APP_SENTRY_DSN }}" | |
| "NEXT_PUBLIC_APP_SENTRY_ORG=${{ vars.NEXT_PUBLIC_SENTRY_ORG }}" | |
| "NEXT_PUBLIC_APP_SENTRY_PII=${{ vars.NEXT_PUBLIC_APP_SENTRY_PII }}" | |
| "NEXT_PUBLIC_APP_SENTRY_PROJECT=${{ vars.NEXT_PUBLIC_APP_SENTRY_PROJECT }}" | |
| "NEXT_PUBLIC_APP_SERVICE_ID=${{ vars.APP_SERVICE_ID }}" | |
| "NEXT_PUBLIC_TYPESENSE_RESOURCE_COLLECTION_NAME=${{ vars.NEXT_PUBLIC_TYPESENSE_RESOURCE_COLLECTION_NAME }}" | |
| "NEXT_PUBLIC_TYPESENSE_HOST=${{ vars.NEXT_PUBLIC_TYPESENSE_HOST }}" | |
| "NEXT_PUBLIC_TYPESENSE_PORT=${{ vars.NEXT_PUBLIC_TYPESENSE_PORT }}" | |
| "NEXT_PUBLIC_TYPESENSE_PROTOCOL=${{ vars.NEXT_PUBLIC_TYPESENSE_PROTOCOL }}" | |
| secrets: | | |
| "AUTH_ENCRYPTION_KEY=${{ secrets.TEST_AUTH_ENCRYPTION_KEY }}" | |
| "AUTH_SIGN_UP=${{ vars.K8S_SECRET_AUTH_SIGN_UP }}" | |
| "CORDIS_API_KEY=${{ secrets.K8S_SECRET_CORDIS_API_KEY }}" | |
| "CORDIS_API_BASE_URL=${{ secrets.K8S_SECRET_CORDIS_API_BASE_URL }}" | |
| "DATABASE_HOST=${{ secrets.K8S_SECRET_DATABASE_HOST }}" | |
| "DATABASE_NAME=${{ secrets.K8S_SECRET_DATABASE_NAME }}" | |
| "DATABASE_PASSWORD=${{ secrets.TEST_DATABASE_PASSWORD }}" | |
| "DATABASE_PORT=${{ secrets.K8S_SECRET_DATABASE_PORT }}" | |
| "DATABASE_USER=${{ secrets.TEST_DATABASE_USER }}" | |
| "EMAIL_ADDRESS=${{ secrets.K8S_SECRET_EMAIL_ADDRESS }}" | |
| "EMAIL_SMTP_PORT=${{ secrets.K8S_SECRET_EMAIL_SMTP_PORT }}" | |
| "EMAIL_SMTP_SERVER=${{ secrets.K8S_SECRET_EMAIL_SMTP_SERVER }}" | |
| "IMGPROXY_BASE_URL=${{ vars.K8S_SECRET_IMGPROXY_BASE_URL }}" | |
| "IMGPROXY_KEY=${{ secrets.TEST_IMGPROXY_KEY }}" | |
| "IMGPROXY_PORT=${{ vars.K8S_SECRET_IMGPROXY_PORT }}" | |
| "IMGPROXY_SALT=${{ secrets.TEST_IMGPROXY_SALT }}" | |
| "MAILCHIMP_API_BASE_URL=${{ secrets.TEST_MAILCHIMP_API_BASE_URL }}" | |
| "MAILCHIMP_API_KEY=${{ secrets.TEST_MAILCHIMP_API_KEY }}" | |
| "MAILCHIMP_LIST_ID=${{ secrets.TEST_MAILCHIMP_LIST_ID }}" | |
| "OPENAIRE_API_BASE_URL=${{ secrets.TEST_OPENAIRE_API_BASE_URL }}" | |
| "S3_ACCESS_KEY=${{ secrets.TEST_S3_ACCESS_KEY }}" | |
| "S3_BUCKET_NAME=${{ vars.K8S_SECRET_S3_BUCKET_NAME }}" | |
| "S3_HOST=${{ vars.K8S_SECRET_S3_HOST }}" | |
| "S3_PORT=${{ vars.K8S_SECRET_S3_PORT }}" | |
| "S3_PROTOCOL=${{ vars.K8S_SECRET_S3_PROTOCOL }}" | |
| "S3_SECRET_KEY=${{ secrets.TEST_S3_SECRET_KEY }}" | |
| "SSHOC_MARKETPLACE_API_BASE_URL: ${{ vars.K8S_SECRET_SSHOC_MARKETPLACE_API_BASE_URL }}" | |
| "SSHOC_MARKETPLACE_BASE_URL: ${{ vars.K8S_SECRET_SSHOC_MARKETPLACE_BASE_URL }}" | |
| "SSHOC_MARKETPLACE_PASSWORD: ${{ secrets.K8S_SECRET_SSHOC_MARKETPLACE_PASSWORD }}" | |
| "SSHOC_MARKETPLACE_USER: ${{ secrets.K8S_SECRET_SSHOC_MARKETPLACE_USER }}" | |
| "TYPESENSE_ADMIN_API_KEY=${{ secrets.K8S_SECRET_TYPESENSE_ADMIN_API_KEY }}" | |
| "ZOTERO_API_KEY=${{ secrets.K8S_SECRET_ZOTERO_API_KEY }}" | |
| "ZOTERO_API_BASE_URL=${{ secrets.K8S_SECRET_ZOTERO_API_BASE_URL }}" | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-migrate: | |
| name: Build and push docker images | |
| needs: [config] | |
| if: needs.config.outputs.has_changes == 'true' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 60 | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Set up docker buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Sign in to the container registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: "ghcr.io" | |
| username: "${{ github.actor }}" | |
| password: "${{ secrets.GITHUB_TOKEN }}" | |
| - name: Extract metadata (tags, labels) for migrate docker image | |
| id: meta-migrate | |
| uses: docker/metadata-action@v6 | |
| with: | |
| images: "ghcr.io/${{ needs.config.outputs.repository }}-migrate" | |
| tags: | | |
| type=raw,value={{sha}} | |
| type=ref,event=branch | |
| - name: Build and push migrate docker image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| target: migrate | |
| push: true | |
| tags: "${{ steps.meta-migrate.outputs.tags }}" | |
| labels: "${{ steps.meta-migrate.outputs.labels }}" | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| deploy: | |
| name: Deploy docker images | |
| needs: [config, build, build-migrate] | |
| if: needs.config.outputs.has_changes == 'true' | |
| uses: dariah-eric/gl-autodevops-minimal-port/.github/workflows/deploy.yml@main | |
| secrets: inherit | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| target: ${{ fromJSON(needs.config.outputs.matrix) }} | |
| max-parallel: 1 | |
| with: | |
| default_port: "3000" | |
| environment: "${{ matrix.target.environment }}" | |
| APP_NAME: "${{ matrix.target.image }}" | |
| APP_ROOT: "/" | |
| DOCKER_TAG: "ghcr.io/${{ github.repository }}-${{ matrix.target.image }}" | |
| PUBLIC_URL: "${{ matrix.target.public_url }}" | |
| SERVICE_ID: "${{ matrix.target.service_id }}" |