1- # GitHub Actions workflow for building and deploying NMRXiv to production environment
2- # This workflow runs tests, builds Docker images, and deploys to the FSU production environment
3- name : Setup, Build and Publish to Prod
1+ # Prod build workflow: builds and pushes Docker images to Prod
2+ # Note: consider
3+ # - setting explicit minimal permissions (e.g., permissions: { contents: read })
4+ # - adding concurrency to cancel superseded runs (group per tag/branch, cancel-in-progress: true)
5+ # - pinning actions to commit SHAs for supply-chain security
6+ name : Build and Deploy to Prod
47
5- # Trigger the workflow only when a release is created
8+ # Runs on manual workflow_dispatch with confirmation
69on :
7- release :
8- types : [published]
10+ workflow_dispatch :
11+ inputs :
12+ confirm :
13+ description : " Type 'DEPLOY' to confirm production deployment"
14+ required : true
15+ type : string
916
1017# Environment variables used across all jobs
1118env :
12- DOCKER_HUB_USERNAME : ${{ secrets.DOCKER_HUB_USERNAME }}
13- DOCKER_HUB_PASSWORD : ${{ secrets.DOCKER_HUB_PASSWORD }}
1419 REPOSITORY_NAME : nmrxiv
1520 REPOSITORY_NAMESPACE : nfdi4chem
1621
1722jobs :
18- # Build Docker images and deploy to production environment
19- setup-build-publish-deploy :
20- name : Build & deploy to production
23+ # Guard: confirm input and authorize actor
24+ guard :
25+ name : Access control and confirmation
2126 runs-on : ubuntu-latest
22- # Only run this job if tests pass successfully
23- # needs: php-unit-test
24- # Use the Dev environment for deployment secrets and protection rules
27+ steps :
28+ - name : Validate actor and confirmation
29+ shell : bash
30+ run : |
31+ echo "Actor: ${GITHUB_ACTOR}"
32+ # Confirm input (workflow_dispatch)
33+ if [[ "${{ github.event.inputs.confirm }}" != "DEPLOY" ]]; then
34+ echo "Confirmation token mismatch. Expected 'DEPLOY'."
35+ exit 1
36+ fi
37+
38+ # Authorize actor (comma/space separated list in secret)
39+ AUTHORIZED_ACTORS="${{ secrets.PROD_DEPLOY_AUTHORIZED_ACTORS }}"
40+ allowed=0
41+ for u in ${AUTHORIZED_ACTORS//,/ }; do
42+ if [[ "${u,,}" == "${GITHUB_ACTOR,,}" ]]; then
43+ allowed=1
44+ break
45+ fi
46+ done
47+ if [[ $allowed -ne 1 ]]; then
48+ echo "User '${GITHUB_ACTOR}' is not authorized to trigger this workflow."
49+ exit 1
50+ fi
51+ echo "Authorization check passed."
52+
53+ # Build and publish Docker images for the production environment
54+ setup-build-publish-deploy-prod :
55+ name : Deploy to prod
56+ runs-on : ubuntu-latest
57+ needs : [guard]
2558 environment :
2659 name : Prod
2760 steps :
28- # Checkout the repository code for building Docker images
61+ # Checkout code
2962 - name : Checkout
3063 uses : actions/checkout@v4
3164
32- # Authenticate with Docker Hub for pushing images
65+ # Fetch latest release tag (fallback to short SHA) and short SHA for tags
66+ - name : Fetch latest release (gh)
67+ id : fetch-latest-release
68+ env :
69+ GITHUB_TOKEN : ${{ github.token }}
70+ run : |
71+ # Get latest published release tag
72+ tag=$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName -q .tagName 2>/dev/null || echo "")
73+ if [[ -z "$tag" ]]; then
74+ echo "No published release found; falling back to short SHA."
75+ tag="${GITHUB_SHA::12}"
76+ fi
77+ echo "tag_name=$tag" >> "$GITHUB_OUTPUT"
78+ # Expose short commit SHA for tags
79+ sha_short="${GITHUB_SHA::12}"
80+ echo "sha_short=$sha_short" >> "$GITHUB_OUTPUT"
81+
82+ # Docker Hub login (uses repository secrets)
3383 - name : Log in to Docker Hub
3484 uses : docker/login-action@v3
3585 with :
36- username : ${{ env .DOCKER_HUB_USERNAME }}
37- password : ${{ env .DOCKER_HUB_PASSWORD }}
86+ username : ${{ secrets .DOCKER_HUB_USERNAME }}
87+ password : ${{ secrets .DOCKER_HUB_PASSWORD }}
3888
39- # Set up Docker Buildx for multi-platform builds
89+ # Set up Docker Buildx
4090 - name : Set up Docker Buildx
4191 uses : docker/setup-buildx-action@v3
4292
43- # Build and push the main application Docker image for FSU deployment
44- - name : Build and push App Docker image
93+ # Build + push app image (tags: release, sha, latest). Uses GHA cache.
94+ - name : Build and push App Docker image
4595 uses : docker/build-push-action@v6
4696 with :
4797 context : .
4898 file : ./deployment/Dockerfile
4999 push : true
50- # Pass proxy settings and release version as build arguments
51100 build-args : |
52- RELEASE_VERSION=${{ github.event.release.tag_name }}
53- # Tag the image with both the release version and latest
101+ RELEASE_VERSION=${{ steps.fetch-latest-release.outputs.tag_name }}
54102 tags : |
55- ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:app-${{ github.event.release.tag_name }}
103+ ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:app-sha-${{ steps.fetch-latest-release.outputs.sha_short }}
104+ ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:app-${{ steps.fetch-latest-release.outputs.tag_name }}
56105 ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:app-latest
57- # Enable build cache for faster builds
58106 cache-from : type=gha
59107 cache-to : type=gha,mode=max
60108
61- # Build and push the worker Docker image for background job processing
109+ # Build + push worker image (tags: release, sha, latest)
62110 - name : Build and push Worker Docker image
63111 uses : docker/build-push-action@v6
64112 with :
65113 context : .
66114 file : ./deployment/Dockerfile.worker
67115 push : true
68- # Pass proxy settings and release version as build arguments
69116 build-args : |
70- RELEASE_VERSION=${{ github.event.release.tag_name }}
71- # Tag the worker image with both the release version and latest
117+ RELEASE_VERSION=${{ steps.fetch-latest-release.outputs.tag_name }}
72118 tags : |
73- ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:worker-${{ github.event.release.tag_name }}
119+ ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:worker-sha-${{ steps.fetch-latest-release.outputs.sha_short }}
120+ ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:worker-${{ steps.fetch-latest-release.outputs.tag_name }}
74121 ${{ env.REPOSITORY_NAMESPACE }}/${{ env.REPOSITORY_NAME }}:worker-latest
75- # Enable build cache for faster builds
76122 cache-from : type=gha
77- cache-to : type=gha,mode=max
78-
79- # Optional: Add deployment step if needed
80- # - name: Deploy to production environment
81- # run: |
82- # echo "Add your deployment commands here"
83- # # Example: kubectl apply -f k8s/ or docker-compose up -d
123+ cache-to : type=gha,mode=max
0 commit comments