Skip to content

Unpin Node.js

Unpin Node.js #1696

Workflow file for this run

name: CI
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
inputs:
heroku-app:
description: Deploy to Heroku app (if set)
type: string
required: false
# Only one run per branch at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
# This is the same as GitHub Action's `bash` keyword as of 20 June 2023:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
#
# Completely spelling it out here so that GitHub can't change it out from under us
# and we don't have to refer to the docs to know the expected behavior.
shell: bash --noprofile --norc -eo pipefail {0}
jobs:
# Lint regardless of build or test status and lint early.
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- run: node --version
- run: npm ci
- run: npm run lint:server
- run: npm run lint:static-site
- run: node ./scripts/check-resource-index-match.js
# Build into Heroku slug so we can deploy the same build that we test.
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/heroku-build
- if: always()
uses: actions/upload-artifact@v4
with:
name: build
path: |
build/slug.tar.gz
build/slug.tar.gz.sha256sum
build/slug.json
# Run tests in Heroku runtime environment against our built slug.
test:
if: github.repository == 'nextstrain/nextstrain.org'
needs: build
runs-on: ubuntu-latest
container:
image: heroku/heroku:22
env:
# Override NODE_ENV=production default in production build (slug)
NODE_ENV: development
# Set up Heroku runtime environment. See bash(1) or
# <https://www.gnu.org/software/bash/manual/bash.html#Invoked-non_002dinteractively>.
BASH_ENV: .heroku/BASH_ENV
steps:
- uses: actions/download-artifact@v4
with:
name: build
path: build/
- run: sha256sum --check build/slug.tar.gz.sha256sum
- run: tar --extract --file build/slug.tar.gz --xform 's,^[.]/app/,,'
- run: node --version
# (Re-)install dev deps which got pruned from production build (slug)
- run: npm ci
# configure AWS to run dev server necessary for `npm run test:ci`
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ vars.AWS_DEFAULT_REGION }}
aws-access-key-id: ${{ secrets.DEV_SERVER_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_SERVER_AWS_SECRET_ACCESS_KEY }}
- run: npm run test:ci
env:
# Tests make GitHub API requests which are rate limited.
# Use the GitHub Actions token for a limit of 1,000 requests per hour.
# <https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api#primary-rate-limit-for-github_token-in-github-actions>
GITHUB_TOKEN: ${{ github.token }}
- if: always()
uses: actions/upload-artifact@v4
with:
name: test-logs
path: test/server.log
index-resources:
if: |2
github.repository == 'nextstrain/nextstrain.org'
&& github.event_name == 'push'
&& github.ref == 'refs/heads/master'
needs: test
permissions:
id-token: write # needed to interact with GitHub's OIDC Token endpoint
contents: read
uses: ./.github/workflows/index-resources.yml
secrets: inherit
deploy:
if: |2
!cancelled()
&& needs.build.result == 'success'
&& needs.test.result == 'success'
&& contains(fromJSON('["success", "skipped"]'), needs.index-resources.result)
&& github.repository == 'nextstrain/nextstrain.org'
&& ( (github.event_name == 'push' && github.ref == 'refs/heads/master')
|| (github.event_name == 'workflow_dispatch' && inputs.heroku-app) )
# Wait for "build", "test", and "index-resources" jobs above to pass.
needs:
- build
- test
- index-resources
# Name a GitHub environment configuration¹ to auto-create deployment
# records in GitHub based on this job's progress/status. Also grants
# access to environment-specific secrets.
#
# The URL is specific to this deployment, not the environment (i.e. an
# environment have deployments at different URLs).
#
# ¹ https://github.com/nextstrain/nextstrain.org/settings/environments
environment:
name: ${{ inputs.heroku-app || 'nextstrain-canary' }}
url: ${{ inputs.heroku-app && format('https://{0}.herokuapp.com', inputs.heroku-app) || 'https://next.nextstrain.org' }}
# Deploy steps
runs-on: ubuntu-latest
env:
HEROKU_APP: ${{ inputs.heroku-app || 'nextstrain-canary' }}
steps:
- uses: actions/download-artifact@v4
with:
name: build
path: build/
- name: Login to Heroku
run: echo "machine api.heroku.com login $HEROKU_USER password $HEROKU_TOKEN" >> ~/.netrc
env:
HEROKU_USER: "${{ vars.HEROKU_USER }}"
HEROKU_TOKEN: "${{ secrets.HEROKU_TOKEN }}"
- name: Upload slug
run: |
# <https://devcenter.heroku.com/articles/platform-api-reference#slug-create>
curl https://api.heroku.com/apps/"$HEROKU_APP"/slugs \
--data-binary @build/slug.json \
--header 'Content-Type: application/json' \
--header 'Accept: application/vnd.heroku+json; version=3' \
--fail --silent --show-error --location --netrc \
| tee slug.json
curl "$(jq -r .blob.url slug.json)" \
--request "$(jq -r .blob.method slug.json | tr a-z A-Z)" \
--header "Content-Type:" \
--data-binary @build/slug.tar.gz \
--fail --location --netrc \
| cat
- name: Release slug
run: |
# <https://devcenter.heroku.com/articles/platform-api-reference#release-create>
curl https://api.heroku.com/apps/"$HEROKU_APP"/releases \
--data-binary @<(jq '{slug: .id}' slug.json) \
--header 'Content-Type: application/json' \
--header 'Accept: application/vnd.heroku+json; version=3' \
--fail --silent --show-error --location --netrc \
| tee release.json
- if: always()
uses: actions/upload-artifact@v4
with:
name: deploy
path: |
slug.json
release.json
- if: always()
name: Logout of Heroku
run: sed -i -e '/^machine api\.heroku\.com/d' ~/.netrc