145 lines
5.3 KiB
YAML
145 lines
5.3 KiB
YAML
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
|