This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
name: Master Production Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
concurrency:
|
||||
group: deploy-production
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
WEB_IMAGE_REPO: ${{ vars.CONTAINER_REGISTRY }}/${{ github.repository_owner }}/${{ github.event.repository.name }}-web
|
||||
RELEASE_ID: ${{ github.sha }}-${{ github.run_number }}
|
||||
NPM_CONFIG_AUDIT: "false"
|
||||
NPM_CONFIG_FUND: "false"
|
||||
NPM_CONFIG_UPDATE_NOTIFIER: "false"
|
||||
|
||||
jobs:
|
||||
production:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Setup npm
|
||||
run: npm install -g npm@11.6.4
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci --prefer-offline --no-audit --no-fund
|
||||
|
||||
- name: Quality gate
|
||||
run: npm run ci:quality
|
||||
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Gitea Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push web image
|
||||
id: build-web
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: deploy/docker/Dockerfile.web
|
||||
push: true
|
||||
tags: ${{ env.WEB_IMAGE_REPO }}:${{ github.sha }}
|
||||
labels: |
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
org.opencontainers.image.version=${{ env.RELEASE_ID }}
|
||||
|
||||
- name: Production pre-deploy checks
|
||||
env:
|
||||
ENVIRONMENT: production
|
||||
STACK_NAME: ${{ vars.PRODUCTION_STACK_NAME }}
|
||||
RELEASE_ID: ${{ env.RELEASE_ID }}
|
||||
COMMIT_SHA: ${{ github.sha }}
|
||||
WEB_IMAGE: ${{ env.WEB_IMAGE_REPO }}@${{ steps.build-web.outputs.digest }}
|
||||
PUBLIC_HOST: ${{ vars.PRODUCTION_PUBLIC_HOST }}
|
||||
TRAEFIK_NETWORK: ${{ vars.PRODUCTION_TRAEFIK_NETWORK }}
|
||||
SWARM_MANAGER_HOST: ${{ secrets.PRODUCTION_SWARM_MANAGER_HOST }}
|
||||
SWARM_SSH_USER: ${{ secrets.PRODUCTION_SWARM_SSH_USER }}
|
||||
run: node deploy/scripts/predeploy-check.mjs
|
||||
|
||||
- name: Deploy production
|
||||
env:
|
||||
ENVIRONMENT: production
|
||||
STACK_NAME: ${{ vars.PRODUCTION_STACK_NAME }}
|
||||
RELEASE_ID: ${{ env.RELEASE_ID }}
|
||||
COMMIT_SHA: ${{ github.sha }}
|
||||
WEB_IMAGE: ${{ env.WEB_IMAGE_REPO }}@${{ steps.build-web.outputs.digest }}
|
||||
PUBLIC_HOST: ${{ vars.PRODUCTION_PUBLIC_HOST }}
|
||||
TRAEFIK_NETWORK: ${{ vars.PRODUCTION_TRAEFIK_NETWORK }}
|
||||
SWARM_MANAGER_HOST: ${{ secrets.PRODUCTION_SWARM_MANAGER_HOST }}
|
||||
SWARM_SSH_USER: ${{ secrets.PRODUCTION_SWARM_SSH_USER }}
|
||||
SWARM_SSH_PORT: ${{ secrets.PRODUCTION_SWARM_SSH_PORT }}
|
||||
REGISTRY: ${{ env.REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
WEB_REPLICAS: ${{ vars.PRODUCTION_WEB_REPLICAS }}
|
||||
WEB_PLACEMENT_CONSTRAINT: ${{ vars.PRODUCTION_WEB_PLACEMENT_CONSTRAINT }}
|
||||
TRAEFIK_ENTRYPOINTS: ${{ vars.TRAEFIK_ENTRYPOINTS }}
|
||||
TRAEFIK_TLS: ${{ vars.TRAEFIK_TLS }}
|
||||
REGION: ${{ vars.REGION }}
|
||||
TEAM_ID: ${{ vars.TEAM_ID }}
|
||||
DEPLOY_MIN_FREE_MB: ${{ vars.DEPLOY_MIN_FREE_MB }}
|
||||
DEPLOY_PRUNE_BEFORE_PULL: ${{ vars.DEPLOY_PRUNE_BEFORE_PULL }}
|
||||
DEPLOY_PRUNE_UNTIL: ${{ vars.DEPLOY_PRUNE_UNTIL }}
|
||||
DEPLOY_CLEANUP_FAILED_IMAGES: ${{ vars.DEPLOY_CLEANUP_FAILED_IMAGES }}
|
||||
VIDEOREG_DB_MEMORY_TTL_MS: ${{ vars.VIDEOREG_DB_MEMORY_TTL_MS }}
|
||||
VIDEOREG_NEXT_CACHE_REVALIDATE_SECONDS: ${{ vars.VIDEOREG_NEXT_CACHE_REVALIDATE_SECONDS }}
|
||||
run: deploy/scripts/deploy-over-ssh.sh
|
||||
|
||||
- name: Production smoke checks
|
||||
id: smoke
|
||||
continue-on-error: true
|
||||
env:
|
||||
BASE_URL: https://${{ vars.PRODUCTION_PUBLIC_HOST }}
|
||||
EXPECTED_RELEASE_ID: ${{ env.RELEASE_ID }}
|
||||
SMOKE_RESULT_PATH: smoke-result.json
|
||||
run: node deploy/scripts/smoke-check.mjs
|
||||
|
||||
- name: Roll back production after failed smoke checks
|
||||
if: steps.smoke.outcome == 'failure'
|
||||
env:
|
||||
ENVIRONMENT: production
|
||||
STACK_NAME: ${{ vars.PRODUCTION_STACK_NAME }}
|
||||
SWARM_MANAGER_HOST: ${{ secrets.PRODUCTION_SWARM_MANAGER_HOST }}
|
||||
SWARM_SSH_USER: ${{ secrets.PRODUCTION_SWARM_SSH_USER }}
|
||||
SWARM_SSH_PORT: ${{ secrets.PRODUCTION_SWARM_SSH_PORT }}
|
||||
run: deploy/scripts/rollback-over-ssh.sh
|
||||
|
||||
- name: Fail after production smoke rollback
|
||||
if: steps.smoke.outcome == 'failure'
|
||||
run: exit 1
|
||||
|
||||
- name: Write release manifest
|
||||
env:
|
||||
COMMIT_SHA: ${{ github.sha }}
|
||||
RELEASE_ID: ${{ env.RELEASE_ID }}
|
||||
WEB_IMAGE_DIGEST: ${{ env.WEB_IMAGE_REPO }}@${{ steps.build-web.outputs.digest }}
|
||||
SMOKE_RESULT_PATH: smoke-result.json
|
||||
WORKFLOW_RUN_ID: ${{ github.run_id }}
|
||||
run: node deploy/scripts/write-release-manifest.mjs > release-manifest.json
|
||||
|
||||
- name: Upload release manifest
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-manifest-${{ env.RELEASE_ID }}
|
||||
path: release-manifest.json
|
||||
Reference in New Issue
Block a user