Skip to content

deploy

deploy #4211

Workflow file for this run

name: deploy
on:
workflow_run:
workflows: ["build"]
types:
- completed
env:
BRANCH_NAME: ${{ github.event.workflow_run.head_branch }}
permissions:
deployments: write
jobs:
create_deployment:
name: Create GitHub deployment
runs-on: ubuntu-latest
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_repository.full_name == 'ToposInstitute/CatColab'
outputs:
deployment_id: ${{ steps.create_deployment.outputs.deployment_id }}
steps:
- name: Create new GitHub deployment
id: create_deployment
uses: chrnorm/deployment-action@v2
with:
token: ${{ github.token }}
environment: netlify-preview
ref: ${{ github.event.workflow_run.head_branch }}
sha: ${{ github.event.workflow_run.head_sha }}
transient-environment: true
auto-inactive: true
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Update deployment status to in_progress
uses: chrnorm/deployment-status@v2
with:
token: ${{ github.token }}
description: 'Building and deploying...'
state: 'in_progress'
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
deployment-id: ${{ steps.create_deployment.outputs.deployment_id }}
deploy:
name: Deploy to Netlify
runs-on: ubuntu-latest
if: >
github.event.workflow_run.conclusion == 'success' &&
(github.event.workflow_run.event != 'pull_request' || github.event.workflow_run.head_repository.full_name == 'ToposInstitute/CatColab')
outputs:
deploy_url: ${{ steps.url_preview.outputs.NETLIFY_PREVIEW_URL }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: 24
cache: "pnpm"
- name: Install Netlify
run: |
cd .netlify-env
pnpm install
- name: Download artifacts
uses: actions/download-artifact@v4
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Consolidate and deploy to Staging
if: github.event.workflow_run.event == 'push' || github.event.workflow_run.event == 'pull_request'
id: netlify_deploy
run: |
mv app site/
mv dev-docs site/dev
mv rust_docs site/dev/rust
mv frontend_docs site/dev/frontend
mv ui-components site/dev/ui-components
mv math-docs site/math
mv rfc site/rfc
echo '/dev/rust /dev/rust/catlog' >> site/_redirects
echo '/dev/core /dev/rust/catlog' >> site/_redirects
echo '/dev/backend /dev/rust/backend' >> site/_redirects
echo '/dev/catcolab_backend /dev/rust/backend' >> site/_redirects
echo '/math /math/index.xml' >> site/_redirects
echo '/maths /math/index.xml' >> site/_redirects
echo '/* /index.html 200' >> site/_redirects
cd .netlify-env
branch_flag=""
if [ "$BRANCH_NAME" = "main" ]; then branch_flag="--prod"; else branch_flag="--alias='branch-$BRANCH_NAME'"; fi
npx netlify deploy --dir ../site --site ${{ secrets.NETLIFY_SITE_ID }} --auth ${{ secrets.NETLIFY_API_TOKEN }} $branch_flag --json > ../deploy_output.json
- name: Consolidate and deploy to Production
if: github.event.workflow_run.event == 'release'
run: |
mv app site/
echo '/* /index.html 200' >> site/_redirects
cd .netlify-env
npx netlify deploy --dir ../site --site ${{ secrets.NETLIFY_PROD_SITE_ID }} --auth ${{ secrets.NETLIFY_API_TOKEN }} --prod
- name: Generate URL preview
id: url_preview
if: env.BRANCH_NAME != 'main' && (github.event.workflow_run.event == 'push' || github.event.workflow_run.event == 'pull_request')
run: |
NETLIFY_PREVIEW_URL=$(jq -r '.deploy_url' deploy_output.json)
echo "NETLIFY_PREVIEW_URL=$NETLIFY_PREVIEW_URL" >> "$GITHUB_OUTPUT"
report_deployment_status:
name: Report deployment status
runs-on: ubuntu-latest
needs: [create_deployment, deploy]
if: always() && github.event.workflow_run.event == 'pull_request' && needs.create_deployment.result == 'success'
steps:
- name: Delete old deployments
if: needs.deploy.result == 'success'
uses: actions/github-script@v7
with:
script: |
const { data: deployments } = await github.rest.repos.listDeployments({
owner: context.repo.owner,
repo: context.repo.repo,
ref: '${{ github.event.workflow_run.head_branch }}',
environment: 'netlify-preview'
});
console.log(`Found ${deployments.length} existing deployment(s)`);
const currentDeploymentId = parseInt('${{ needs.create_deployment.outputs.deployment_id }}');
for (const deployment of deployments) {
if (deployment.id !== currentDeploymentId) {
console.log(`Deleting old deployment ${deployment.id}`);
// A deployment must be marked inactive before it can be deleted
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.id,
state: 'inactive',
description: 'Superseded by newer deployment'
});
await github.rest.repos.deleteDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.id
});
console.log(`Deleted deployment ${deployment.id}`);
}
}
- name: Update deployment status to success
if: needs.deploy.result == 'success'
uses: chrnorm/deployment-status@v2
# The deployment may have already been deleted by another run so we need to be ok with errors
continue-on-error: true
with:
token: ${{ github.token }}
environment-url: ${{ needs.deploy.outputs.deploy_url }}
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
description: 'Netlify preview deployment'
state: 'success'
deployment-id: ${{ needs.create_deployment.outputs.deployment_id }}
- name: Update deployment status to failure
if: needs.deploy.result != 'success'
uses: chrnorm/deployment-status@v2
# The deployment may have already been deleted by another run so we need to be ok with errors
continue-on-error: true
with:
token: ${{ github.token }}
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
description: 'Deployment failed'
state: 'failure'
deployment-id: ${{ needs.create_deployment.outputs.deployment_id }}
create_backend_deployment:
name: Create backend GitHub deployment
runs-on: ubuntu-latest
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event != 'pull_request' &&
github.event.workflow_run.head_branch == 'main'
outputs:
deployment_id: ${{ steps.create_deployment.outputs.deployment_id }}
steps:
- name: Create new GitHub deployment
id: create_deployment
uses: chrnorm/deployment-action@v2
with:
token: ${{ github.token }}
environment: backend-next
ref: ${{ github.event.workflow_run.head_branch }}
sha: ${{ github.event.workflow_run.head_sha }}
auto-inactive: true
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Update deployment status to in_progress
uses: chrnorm/deployment-status@v2
with:
token: ${{ github.token }}
description: 'Deploying backend to AWS...'
state: 'in_progress'
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
deployment-id: ${{ steps.create_deployment.outputs.deployment_id }}
deploy_backend:
name: Deploy backend to AWS
runs-on: ubuntu-latest
needs: [create_backend_deployment]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v25
- name: Configure Cachix
uses: cachix/cachix-action@v14
with:
name: catcolab-jmoggr
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Set the SSH key for deployment to catcolab-next
run: |
mkdir -p ~/.ssh
echo "${{ secrets.CATCOLAB_NEXT_DEPLOYUSER_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan backend-next.catcolab.org >> ~/.ssh/known_hosts
- name: Deploy to catcolab-next
run: |
nix run github:serokell/deploy-rs -- --skip-checks .#catcolab-next
- name: Verify deployment
run: |
EXPECTED=$(nix eval --raw .#nixosConfigurations.catcolab-next.config.system.build.toplevel)
ACTUAL=$(ssh catcolab@backend-next.catcolab.org "readlink -f /run/current-system")
if [[ "$ACTUAL" != "$EXPECTED" ]]; then
echo "ERROR: Deployment verification failed, the server is not running the expected nix profile"
echo "Expected: $EXPECTED"
echo "Actual: $ACTUAL"
exit 1
fi
echo "Deployment verified: $ACTUAL"
# Ensure that a copy of the deployed repository is on the machine that it was deployed to. This is
# a nice-to-have which enables checking the configuration of the currently deployed system and could
# make recovery slightly less aweful in the event nix commands need to be run on the remote.
- name: Rsync the repo to remote host
run: |
rsync -az --delete ./ catcolab@backend-next.catcolab.org:~/catcolab
report_backend_deployment_status:
name: Report backend deployment status
runs-on: ubuntu-latest
needs: [create_backend_deployment, deploy_backend]
if: always() && needs.create_backend_deployment.result == 'success'
steps:
- name: Update deployment status to success
if: needs.deploy_backend.result == 'success'
uses: chrnorm/deployment-status@v2
with:
token: ${{ github.token }}
environment-url: https://backend-next.catcolab.org
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
description: 'Backend deployed to AWS'
state: 'success'
deployment-id: ${{ needs.create_backend_deployment.outputs.deployment_id }}
- name: Update deployment status to failure
if: needs.deploy_backend.result != 'success'
uses: chrnorm/deployment-status@v2
with:
token: ${{ github.token }}
log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
description: 'Backend deployment failed'
state: 'failure'
deployment-id: ${{ needs.create_backend_deployment.outputs.deployment_id }}