Skip to content

Redesign of Julia interop, avoiding Jupyter kernel #2814

Redesign of Julia interop, avoiding Jupyter kernel

Redesign of Julia interop, avoiding Jupyter kernel #2814

Workflow file for this run

name: deploy
on:
push:
branches:
- main
pull_request:
release:
types: [published]
env:
BRANCH_NAME: ${{ github.ref_name }}
permissions:
deployments: write
jobs:
create_deployment:
name: Create GitHub deployment
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.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.pull_request.head.ref }}
sha: ${{ github.event.pull_request.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 }}
build_dev_docs:
name: Build developer docs
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# Need full history for `git log` for cache key
fetch-depth: 0
- name: Compute cache key
id: cache-key
run: |
hash=$(git log -1 --format="%H" -- dev-docs)
echo "git-hash=${hash}" >> $GITHUB_OUTPUT
echo "Dev docs hash: ${hash}"
- name: Cache dev docs build
id: cache-dev-docs-build
uses: actions/cache@v4
with:
path: dev-docs/output
key: dev-docs-build-${{ steps.cache-key.outputs.git-hash }}
- name: Setup pnpm
if: steps.cache-dev-docs-build.outputs.cache-hit != 'true'
uses: pnpm/action-setup@v4
- name: Setup NodeJS
if: steps.cache-dev-docs-build.outputs.cache-hit != 'true'
uses: actions/setup-node@v4
with:
node-version: 24
cache: "pnpm"
- name: Build developer docs
if: steps.cache-dev-docs-build.outputs.cache-hit != 'true'
run: |
pnpm install
pnpm --filter ./dev-docs run doc
- name: Report cache status
run: |
if [ "${{ steps.cache-dev-docs-build.outputs.cache-hit }}" = "true" ]; then
echo "✅ Dev docs restored from cache"
else
echo "🔨 Dev docs built and cached"
fi
- name: Upload developer docs
uses: actions/upload-artifact@v4
with:
name: dev-docs
path: dev-docs/output
build_frontend:
name: Build frontend
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# Need full history for `git log` for cache key
fetch-depth: 0
- name: Compute cache key
id: cache-key
run: |
# Get git hash of the most recent commit affecting frontend or any of its dependencies
hash=$(git log -1 --format="%H" -- packages/frontend packages/backend/pkg packages/catlog packages/catlog-wasm packages/notebook-types packages/ui-components Cargo.toml Cargo.lock)
echo "git-hash=${hash}" >> $GITHUB_OUTPUT
echo "Frontend git hash: ${git_hash}"
- name: Cache frontend build
id: cache-frontend-build
# Skip caching for production builds
if: github.event_name != 'release'
uses: actions/cache@v4
with:
path: |
packages/frontend/dist
key: frontend-build-${{ steps.cache-key.outputs.git-hash }}-${{ github.event_name == 'release' && 'production' || 'staging' }}
- name: Setup pnpm
if: github.event_name == 'release' || steps.cache-frontend-build.outputs.cache-hit != 'true'
uses: pnpm/action-setup@v4
- name: Setup NodeJS
if: github.event_name == 'release' || steps.cache-frontend-build.outputs.cache-hit != 'true'
uses: actions/setup-node@v4
with:
node-version: 24
cache: "pnpm"
- name: Install Rust toolchain from file
if: github.event_name == 'release' || steps.cache-frontend-build.outputs.cache-hit != 'true'
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# Don't override flags in cargo config files.
rustflags: ""
- name: Build for Staging
if: (github.event_name == 'push' || github.event_name == 'pull_request') && steps.cache-frontend-build.outputs.cache-hit != 'true'
run: |
pnpm install
# Uses env from packages/frontend/.env.staging
pnpm --filter ./packages/frontend run build -- --mode staging
- name: Build for Production
if: github.event_name == 'release'
run: |
pnpm install
# Uses env from packages/frontend/.env.production
pnpm --filter ./packages/frontend run build
- name: Report cache status
run: |
if [ "${{ github.event_name }}" = "release" ]; then
echo "🔨 Frontend production build completed (cache disabled)"
elif [ "${{ steps.cache-frontend-build.outputs.cache-hit }}" = "true" ]; then
echo "✅ Frontend build restored from cache"
else
echo "🔨 Frontend build completed and cached"
fi
- name: Upload
uses: actions/upload-artifact@v4
with:
name: app
path: packages/frontend/dist
- name: Cache frontend docs build
id: cache-frontend-docs
uses: actions/cache@v4
with:
path: packages/frontend/docs
key: frontend-docs-${{ steps.cache-key.outputs.git-hash }}
- name: Build frontend docs
if: steps.cache-frontend-docs.outputs.cache-hit != 'true'
run: |
pnpm --filter ./packages/frontend run doc
- name: Report frontend docs cache status
run: |
if [ "${{ steps.cache-frontend-docs.outputs.cache-hit }}" = "true" ]; then
echo "✅ Frontend docs restored from cache"
else
echo "🔨 Frontend docs built and cached"
fi
- name: Upload frontend docs
uses: actions/upload-artifact@v4
with:
name: frontend_docs
path: packages/frontend/docs
build_rust_docs:
name: Build Rust docs
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# Need full history for `git log` for cache key
fetch-depth: 0
- name: Compute cache key
id: cache-key
run: |
# Get git hash for all Rust packages
hash=$(git log -1 --format="%H" -- packages/catlog packages/catlog-wasm packages/backend packages/notebook-types Cargo.toml Cargo.lock)
echo "git-hash=${hash}" >> $GITHUB_OUTPUT
echo "Rust hash: ${hash}"
- name: Cache Rust docs build
id: cache-rust-docs
uses: actions/cache@v4
with:
path: target/doc
key: rust-docs-${{ steps.cache-key.outputs.git-hash }}
- name: Install Rust toolchain from file
if: steps.cache-rust-docs.outputs.cache-hit != 'true'
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Build Rust docs
if: steps.cache-rust-docs.outputs.cache-hit != 'true'
run: |
cargo doc --all-features --no-deps --workspace --exclude "migrator"
- name: Report cache status
run: |
if [ "${{ steps.cache-rust-docs.outputs.cache-hit }}" = "true" ]; then
echo "✅ Rust docs restored from cache"
else
echo "🔨 Rust docs built and cached"
fi
- name: Upload Rust docs
uses: actions/upload-artifact@v4
with:
name: rust_docs
path: target/doc
build_math-docs:
name: Build mathematical docs
runs-on: ubuntu-latest
steps:
- name: Repository Checkout
uses: actions/checkout@v4
with:
# Need full history for `git log` for cache key
fetch-depth: 0
- name: Compute cache key
id: cache-key
run: |
hash=$(git log -1 --format="%H" -- math-docs)
echo "git-hash=${hash}" >> $GITHUB_OUTPUT
echo "Math docs hash: ${hash}"
- name: Cache math docs build
id: cache-math-docs
uses: actions/cache@v4
with:
path: math-docs/output
key: math-docs-${{ steps.cache-key.outputs.git-hash }}
- name: Setup TinyTeX
if: steps.cache-math-docs.outputs.cache-hit != 'true'
uses: r-lib/actions/setup-tinytex@v2
- name: Install TeX Packages
if: steps.cache-math-docs.outputs.cache-hit != 'true'
run: |
tlmgr update --self
tlmgr install dvisvgm
tlmgr install standalone
tlmgr install pgf
tlmgr install tikz-cd
tlmgr install amsmath
tlmgr install quiver
tlmgr install spath3
- name: Build mathematical docs
if: steps.cache-math-docs.outputs.cache-hit != 'true'
run: |
cd math-docs
./forester build
- name: Report cache status
run: |
if [ "${{ steps.cache-math-docs.outputs.cache-hit }}" = "true" ]; then
echo "✅ Math docs restored from cache"
else
echo "🔨 Math docs built and cached"
fi
- name: Upload mathematical docs
uses: actions/upload-artifact@v4
with:
name: math-docs
path: math-docs/output
build_ui_components:
name: Build ui-components Storybook
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# Need full history for `git log` for cache key
fetch-depth: 0
- name: Compute cache key
id: cache-key
run: |
hash=$(git log -1 --format="%H" -- packages/ui-components)
echo "git-hash=${hash}" >> $GITHUB_OUTPUT
echo "UI Components hash: ${hash}"
- name: Cache ui-components build
id: cache-ui-components
uses: actions/cache@v4
with:
path: packages/ui-components/storybook-static
key: ui-components-${{ steps.cache-key.outputs.git-hash }}
- name: Setup pnpm
if: steps.cache-ui-components.outputs.cache-hit != 'true'
uses: pnpm/action-setup@v4
- name: Setup NodeJS
if: steps.cache-ui-components.outputs.cache-hit != 'true'
uses: actions/setup-node@v4
with:
node-version: 24
cache: "pnpm"
- name: Install dependencies
if: steps.cache-ui-components.outputs.cache-hit != 'true'
run: pnpm install
- name: Build ui-components Storybook
if: steps.cache-ui-components.outputs.cache-hit != 'true'
run: pnpm --filter ./packages/ui-components run build
- name: Report cache status
run: |
if [ "${{ steps.cache-ui-components.outputs.cache-hit }}" = "true" ]; then
echo "✅ UI Components Storybook restored from cache"
else
echo "🔨 UI Components Storybook built and cached"
fi
- name: Upload ui-components Storybook
uses: actions/upload-artifact@v4
with:
name: ui-components
path: packages/ui-components/storybook-static
deploy:
name: Deploy to Netlify
runs-on: ubuntu-latest
needs: [build_dev_docs, build_frontend, build_rust_docs, build_math-docs, build_ui_components]
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.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
- name: Consolidate and deploy to Staging
if: github.event_name == 'push' || github.event_name == '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
echo '/dev/rust /dev/rust/catlog' >> site/_redirects
echo '/dev/core /dev/rust/catlog' >> 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_name == '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_name == 'push' || github.event_name == '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_name == 'pull_request' && needs.create_deployment.result == 'success'
steps:
- name: Invalidate old successful 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: context.payload.pull_request.head.ref,
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) {
// Get the latest status for this deployment
const { data: statuses } = await github.rest.repos.listDeploymentStatuses({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.id
});
// Only invalidate if the latest status was 'success'
if (statuses.length > 0 && statuses[0].state === 'success') {
console.log(`Invalidating successful deployment ${deployment.id}`);
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.id,
state: 'inactive',
description: 'Superseded by newer deployment'
});
} else {
console.log(`Skipping deployment ${deployment.id} (not successful)`);
}
}
}
- name: Update deployment status to success
if: needs.deploy.result == 'success'
uses: chrnorm/deployment-status@v2
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
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 }}
deploy_backend:
name: Deploy backend to AWS
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' && github.ref_name == 'main'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v25
with:
nix_path: nixpkgs=channel:25.05
- 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
# 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 ./ [email protected]:~/catcolab