Skip to content
Latchkey

prod workflow (CesiumGS/cesium)

The prod workflow from CesiumGS/cesium, explained and optimized by Latchkey.

D

CI health: D - needs work

Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: CesiumGS/cesium.github/workflows/prod.ymlLicense Apache-2.0View source

What it does

This is the prod workflow from the CesiumGS/cesium repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: prod
on:
  push:
    branches:
      - "cesium.com"
env:
  PROD: true
  AWS_ACCESS_KEY_ID: ${{ secrets.PROD_AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}
  AWS_REGION: us-east-1
  BRANCH: ${{ github.ref_name }}
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  GITHUB_REPO: ${{ github.repository }}
  GITHUB_SHA: ${{ github.sha }}
jobs:

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"
      - name: npm install
        run: npm install
      - name: lint *.js
        run: npm run eslint
      - name: lint *.md
        run: npm run markdownlint
      - name: format code
        run: npm run prettier-check
      - name: build
        run: npm run build
      - name: tsc
        run: npm run tsc
      - name: sg test
        run: npm exec --package=@ast-grep/cli --offline -- sg test
      - name: sg scan
        run: npm exec --package=@ast-grep/cli --offline -- sg scan --context 3

  deploy-archive:
    runs-on: ubuntu-latest
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build website release
        run: npm run website-release
      - name: build types
        run: npm run build-ts
      - name: build sandcastle
        # We need to rebuild Sandcastle or the origins will be wrong and not load
        env:
          # We specifically want this to NOT build for production in order to get relative routes
          # to the rest of the archive release files.
          # This also mimics how the zip was generated locally during the release process
          PROD: false
        run: npm run build-sandcastle -- --outer-origin="https://cesium.com"
      - name: deploy to cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Download zip from the Github release and unzip to Build/release/
        # Publish that unzipped code to the bucket for https://cesium.com/downloads/cesiumjs/releases/[version]/... urls
        # Publish sandcastle nested into the bucket for the archive
        run: |
          curl -LO $(curl https://api.github.com/repos/CesiumGS/cesium/releases/latest -H "Authorization: ${GITHUB_TOKEN}" | jq -r '.assets[0].browser_download_url')
          unzip Cesium-$(cat package.json | jq -r '.version' | sed 's/\.0$//').zip -d Build/release/ -x "Apps"
          aws s3 sync Build/release/ s3://cesium-website/cesiumjs/releases/$(cat package.json | jq -r '.version' | sed 's/\.0$//')/ \
            --cache-control "public, max-age=1800" \
            --exclude "Apps/Sandcastle2/*" \
            --delete
          aws s3 sync Apps/Sandcastle2/ s3://cesium-website/cesiumjs/releases/$(cat package.json | jq -r '.version' | sed 's/\.0$//')/Apps/Sandcastle2/ --cache-control "public, max-age=1800" --delete

  deploy-docs:
    runs-on: ubuntu-latest
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build docs
        run: npm run build-docs
      - name: deploy to cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Publish the documentation files to the bucket for https://cesium.com/learn/cesiumjs/ref-doc/
        run: |
          aws s3 sync Build/Documentation/ s3://cesium-website/cesiumjs/ref-doc/ --cache-control "public, max-age=1800" --delete

  deploy-cesium-viewer:
    runs-on: ubuntu-latest
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build website release
        run: npm run website-release
      - name: build cesium viewer
        run: npm run build-cesium-viewer
      - name: deploy to cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Publish the simple viewer app to the bucket for https://cesium.com/cesiumjs/cesium-viewer/
        run: |
          aws s3 sync Build/CesiumViewer/ s3://cesium-website/cesiumjs/cesium-viewer/ --cache-control "public, max-age=1800" --delete

  deploy-sandcastle:
    runs-on: ubuntu-latest
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build website release
        run: npm run website-release
      - name: build types
        run: npm run build-ts
      - name: build apps
        run: npm run build-sandcastle -- --outer-origin="https://sandcastle.cesium.com"
      - name: deploy to sandcastle.cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Publish sandcastle to the bucket for https://sandcastle.cesium.com/
        run: |
          aws s3 sync Build/Sandcastle2/ s3://cesium-sandcastle-website/ --cache-control "public, max-age=1800" --delete

  delete-old-ion-token:
    runs-on: ubuntu-latest
    needs: [deploy-cesium-viewer, deploy-sandcastle]
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          node-version: "22"
      - name: npm install
        working-directory: ./.github/actions/update-tokens
        run: npm install
      - name: run script
        env:
          ION_TOKEN_CONTROLLER_TOKEN: ${{ secrets.ION_TOKEN_CONTROLLER_TOKEN }}
        working-directory: "./.github/actions/update-tokens"
        run: node ionTokenDeleter.js --update

The same workflow, on Latchkey

Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.

name: prod
on:
  push:
    branches:
      - "cesium.com"
env:
  PROD: true
  AWS_ACCESS_KEY_ID: ${{ secrets.PROD_AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}
  AWS_REGION: us-east-1
  BRANCH: ${{ github.ref_name }}
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  GITHUB_REPO: ${{ github.repository }}
  GITHUB_SHA: ${{ github.sha }}
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
 
  lint:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          cache: 'npm'
          node-version: "22"
      - name: npm install
        run: npm install
      - name: lint *.js
        run: npm run eslint
      - name: lint *.md
        run: npm run markdownlint
      - name: format code
        run: npm run prettier-check
      - name: build
        run: npm run build
      - name: tsc
        run: npm run tsc
      - name: sg test
        run: npm exec --package=@ast-grep/cli --offline -- sg test
      - name: sg scan
        run: npm exec --package=@ast-grep/cli --offline -- sg scan --context 3
 
  deploy-archive:
    timeout-minutes: 30
    runs-on: latchkey-small
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          cache: 'npm'
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build website release
        run: npm run website-release
      - name: build types
        run: npm run build-ts
      - name: build sandcastle
        # We need to rebuild Sandcastle or the origins will be wrong and not load
        env:
          # We specifically want this to NOT build for production in order to get relative routes
          # to the rest of the archive release files.
          # This also mimics how the zip was generated locally during the release process
          PROD: false
        run: npm run build-sandcastle -- --outer-origin="https://cesium.com"
      - name: deploy to cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Download zip from the Github release and unzip to Build/release/
        # Publish that unzipped code to the bucket for https://cesium.com/downloads/cesiumjs/releases/[version]/... urls
        # Publish sandcastle nested into the bucket for the archive
        run: |
          curl -LO $(curl https://api.github.com/repos/CesiumGS/cesium/releases/latest -H "Authorization: ${GITHUB_TOKEN}" | jq -r '.assets[0].browser_download_url')
          unzip Cesium-$(cat package.json | jq -r '.version' | sed 's/\.0$//').zip -d Build/release/ -x "Apps"
          aws s3 sync Build/release/ s3://cesium-website/cesiumjs/releases/$(cat package.json | jq -r '.version' | sed 's/\.0$//')/ \
            --cache-control "public, max-age=1800" \
            --exclude "Apps/Sandcastle2/*" \
            --delete
          aws s3 sync Apps/Sandcastle2/ s3://cesium-website/cesiumjs/releases/$(cat package.json | jq -r '.version' | sed 's/\.0$//')/Apps/Sandcastle2/ --cache-control "public, max-age=1800" --delete
 
  deploy-docs:
    timeout-minutes: 30
    runs-on: latchkey-small
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          cache: 'npm'
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build docs
        run: npm run build-docs
      - name: deploy to cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Publish the documentation files to the bucket for https://cesium.com/learn/cesiumjs/ref-doc/
        run: |
          aws s3 sync Build/Documentation/ s3://cesium-website/cesiumjs/ref-doc/ --cache-control "public, max-age=1800" --delete
 
  deploy-cesium-viewer:
    timeout-minutes: 30
    runs-on: latchkey-small
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          cache: 'npm'
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build website release
        run: npm run website-release
      - name: build cesium viewer
        run: npm run build-cesium-viewer
      - name: deploy to cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Publish the simple viewer app to the bucket for https://cesium.com/cesiumjs/cesium-viewer/
        run: |
          aws s3 sync Build/CesiumViewer/ s3://cesium-website/cesiumjs/cesium-viewer/ --cache-control "public, max-age=1800" --delete
 
  deploy-sandcastle:
    timeout-minutes: 30
    runs-on: latchkey-small
    needs: [lint]
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          cache: 'npm'
          node-version: "22"
      - name: npm install
        run: npm install
      - name: build website release
        run: npm run website-release
      - name: build types
        run: npm run build-ts
      - name: build apps
        run: npm run build-sandcastle -- --outer-origin="https://sandcastle.cesium.com"
      - name: deploy to sandcastle.cesium.com
        if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
        # Publish sandcastle to the bucket for https://sandcastle.cesium.com/
        run: |
          aws s3 sync Build/Sandcastle2/ s3://cesium-sandcastle-website/ --cache-control "public, max-age=1800" --delete
 
  delete-old-ion-token:
    timeout-minutes: 30
    runs-on: latchkey-small
    needs: [deploy-cesium-viewer, deploy-sandcastle]
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v7
      - name: install node 22
        uses: actions/setup-node@v6
        with:
          cache: 'npm'
          node-version: "22"
      - name: npm install
        working-directory: ./.github/actions/update-tokens
        run: npm install
      - name: run script
        env:
          ION_TOKEN_CONTROLLER_TOKEN: ${{ secrets.ION_TOKEN_CONTROLLER_TOKEN }}
        working-directory: "./.github/actions/update-tokens"
        run: node ionTokenDeleter.js --update
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 6 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow