Skip to content

chore: CI Refactor #3306

chore: CI Refactor

chore: CI Refactor #3306

Workflow file for this run

name: Continuous Integration
on: # rebuild any PRs and main branch changes
pull_request:
push:
branches:
- main
- 'releases/*'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# FIXME: Find a better name
IS_RELEASE_BRANCH: |
${{
(github.ref == 'refs/heads/main'
|| startsWith(github.ref, 'refs/tags/')
|| startsWith(github.ref, 'refs/heads/releases'))
&& github.event_name != 'pull_request'
}}
# NODE_OPTIONS: --max_old_space_size=4096
jobs:
# Compile native bridge code and isolate extension for Windows, Mac and Linux.
# Uploads the packages as a build artifact to be tested later.
compile-binaries:
strategy:
fail-fast: true
matrix:
include:
# Use Buildjet's Unbuntu 18.04 builders to preserve compatibility with glibc 2.17
- os: ubuntu
runner: buildjet-2vcpu-ubuntu-1804
target: x86_64-unknown-linux-gnu
- os: ubuntu
runner: buildjet-2vcpu-ubuntu-1804
target: aarch64-unknown-linux-gnu
rustflags: '-C linker=aarch64-linux-gnu-gcc'
- os: macos
runner: macos-latest
target: x86_64-apple-darwin
- os: macos
runner: macos-latest
target: aarch64-apple-darwin
- os: windows
runner: windows-latest
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.runner }}
container: ${{ matrix.container }}
defaults:
run:
shell: bash
steps:
- name: 'Checkout code'
uses: actions/checkout@v3
with:
submodules: recursive
- name: 'Cache index.node'
id: cached-artifact
uses: actions/cache@v3
with:
path: ./packages/core-bridge/releases
key: corebridge-artifactcache-${{ matrix.target }}-${{ hashFiles('./packages/core-bridge/**/Cargo.lock', './packages/core-bridge/**/*.rs') }}
- name: Install Rust
if: steps.cached-artifact.outputs.cache-hit != 'true'
uses: dtolnay/rust-toolchain@stable
with:
target: ${{ matrix.target }}
- name: Install protoc
if: steps.cached-artifact.outputs.cache-hit != 'true'
uses: arduino/setup-protoc@v1
with:
version: '3.x'
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Print libc version
if: (steps.cached-artifact.outputs.cache-hit != 'true') && (matrix.os == 'ubuntu')
run: ldd --version
- name: Install gcc-aarch64-linux-gnu
if: (steps.cached-artifact.outputs.cache-hit != 'true') && (matrix.target == 'aarch64-unknown-linux-gnu')
run: sudo apt update && sudo apt install -y gcc-aarch64-linux-gnu
- name: Rust Cargo and Build cache
if: steps.cached-artifact.outputs.cache-hit != 'true'
uses: Swatinem/rust-cache@v2
with:
workspaces: packages/core-bridge -> target
prefix-key: corebridge-buildcache
shared-key: ${{ matrix.target }}
env-vars: ''
# save-if: (github.ref == 'refs/heads/main')
- name: Cross compile rust code
if: steps.cached-artifact.outputs.cache-hit != 'true'
env:
RUSTFLAGS: ${{ matrix.rustflags }}
working-directory: ./packages/core-bridge
run: |
cargo build --release --target ${{ matrix.target }}
find ./target/${{ matrix.target }}/ -ls
mkdir -p ./releases/${{ matrix.target }}
for i in ./target/${{ matrix.target }}/release/{libtemporal_sdk_typescript_bridge.{dylib,so},temporal_sdk_typescript_bridge.dll} ; do
ls [[ -x $i ]] && -l matrix.target }}
cp -a $i ./releases/${{ matrix.target }}/index.node || true
done
- uses: actions/upload-artifact@v3
with:
name: corebridge-native-${{ matrix.target }}
# Actual file will be named ${{ matrix.target }}/index.node
path: ./packages/core-bridge/releases/*/index.node
build-packages:
needs:
- compile-binaries
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Download core-bridge native libraries
uses: actions/download-artifact@v3
with:
path: ./packages/core-bridge/releases/tmp
- name: Put native files into place
working-directory: ./packages/core-bridge/releases
run: |
mv tmp/corebridge-*/* ./
rm -rf tmp
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 16
- name: Get NPM cache directory
id: npm-cache-dir
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
- name: Restore NPM cache
uses: actions/cache/restore@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: npm-main-ubuntu-${{ hashFiles('./package-lock.json') }}
restore-keys: |
npm-main-ubuntu-
- name: Download dependencies
run: |
npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose
- name: Compile code
run: npm run build -- --ignore @temporalio/core-bridge
- name: Publish to Verdaccio
run: node scripts/publish-to-verdaccio.js --registry-dir ./tmp/registry
- name: Save Verdaccio repo artifact
uses: actions/upload-artifact@v3
with:
name: verdaccio-repo
path: ./tmp/registry/storage
- name: Save NPM cache
uses: actions/cache/save@v3
# Only saves NPM cache from the main branch, to reduce pressure on the cache (limited to 10GB).
# if: github.ref == 'refs/heads/main' # FIXME
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: npm-main-ubuntu-${{ hashFiles('./package-lock.json') }}
integration-tests:
needs:
- compile-binaries
strategy:
fail-fast: false
matrix:
node: [14, 16, 18, 20]
os: [ubuntu, macos, windows]
reuse-v8-context: [true, false]
server: [cli] # FIXME: Add 'cloud', 'testenv'
# exclude:
# FIXME: Disable 'cloud' if 'TEMPORAL_CLIENT_CERT' isn't set
# - server: "${{ env.TEMPORAL_CLIENT_CERT == '' && 'cloud' || 'ignore' }}"
include:
- os: ubuntu
runner: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: macos
runner: macos-latest
target: x86_64-apple-darwin
- os: windows
runner: windows-latest
target: x86_64-pc-windows-msvc
runs-on: ${{ matrix.runner }}
defaults:
run:
shell: bash
steps:
- name: Print build information
run: 'echo head_ref: ${{ github.head_ref }}, ref: ${{ github.ref }}, os: ${{ matrix.os }}, node: ${{ matrix.node }}'
- name: 'Checkout code'
uses: actions/checkout@v3
with:
submodules: recursive
- name: Download core-bridge native libraries
uses: actions/download-artifact@v3
with:
name: corebridge-native-${{ matrix.target }}
path: ./packages/core-bridge/releases
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Get NPM cache directory
id: npm-cache-dir
shell: bash
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
- name: Restore NPM cache
uses: actions/cache/restore@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: npm-main-${{ runner.os }}-${{ hashFiles('./package-lock.json') }}
restore-keys: |
npm-main-${{ runner.os }}-
- name: Download dependencies
run: |
npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose
- name: Compile code
run: npm run build -- --ignore @temporalio/core-bridge
- name: Install Temporal CLI
if: ${{ matrix.server == 'cli' }}
uses: temporalio/setup-temporal@v0
- name: Runs Temporal CLI
if: ${{ matrix.server == 'cli' }}
shell: bash
run: |
temporal server start-dev --headless &
- name: Print out Node heap statistics
run: node -e 'console.log(v8.getHeapStatistics())'
- name: Run Tests
run: npm test
env:
RUN_INTEGRATION_TESTS: ${{ matrix.server == 'cli' }}
REUSE_V8_CONTEXT: ${{ matrix.reuse-v8-context }}
- uses: actions/upload-artifact@v3
if: failure()
with:
name: integration-tests-${{ matrix.os }}-node${{ matrix.node }}-${{ matrix.server }}-logs
path: |
~/.npm/_logs/
C:\npm\cache\_logs\
# Tests that npm init @temporalio results in a working worker and client
test-npm-init:
needs: build-packages
strategy:
fail-fast: false
matrix:
node: [14, 16, 18]
os: [ubuntu, macos, windows]
sample: [hello-world, fetch-esm, hello-world-mtls]
server: [cli, cloud]
exclude:
# Disable non-mtls tests on cloud
- sample: hello-world
server: cloud
# Disable mtls tests on cli
- sample: hello-world-mtls
server: cli
- sample: fetch-esm
server: cloud
# FIXME: investigate why 'fetch-esm' always hangs on Windows
- sample: fetch-esm
os: windows
# FIXME: Disable 'cloud' if 'TEMPORAL_CLIENT_CERT' isn't set
# - server: "${{ env.TEMPORAL_CLIENT_CERT == '' && 'cloud' || 'ignore' }}"
include:
- os: ubuntu
runner: ubuntu-latest
- os: macos
runner: macos-latest
- os: windows
runner: windows-latest
runs-on: ${{ matrix.runner }}
env:
TEMPORAL_CLIENT_CERT: ${{ secrets.TEMPORAL_CLIENT_CERT }}
TEMPORAL_CLIENT_KEY: ${{ secrets.TEMPORAL_CLIENT_KEY }}
steps:
- name: 'Checkout code'
uses: actions/checkout@v3
with:
# We don't need the core submodule here since won't build the project
submodules: false
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
- name: Get NPM cache directory
id: npm-cache-dir
shell: bash
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
- name: Restore NPM cache
uses: actions/cache/restore@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: npm-main-${{ runner.os }}-${{ hashFiles('./package-lock.json') }}
restore-keys: |
npm-main-${{ runner.os }}-
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
# No need to compile anything, we just need the package ./scripts and their dependencies
- name: Install dependencies without compilation
run: |
npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
- name: Restore Verdaccio repo artifact
uses: actions/download-artifact@v3
with:
name: verdaccio-repo
path: ./tmp/registry/storage
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
- run: find . -ls
shell: bash
working-directory: ./tmp/registry/storage
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
# Note: here, `npx create` fails on windows if shell is bash.
- name: Instantiate sample project using verdaccio artifacts
run: node scripts/init-from-verdaccio.js --registry-dir ./tmp/registry --sample https://github.com/temporalio/samples-typescript/tree/next/${{ matrix.sample }} --target-dir ${{ runner.temp }}/example
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
# FIXME: Move this to an independant github action
- name: Install Temporal CLI
if: ${{ matrix.server == 'cli' }}
uses: temporalio/setup-temporal@v0
- name: Runs Temporal CLI
if: ${{ matrix.server == 'cli' }}
shell: bash
run: |
temporal server start-dev --headless &
- name: Print out Node heap statistics
run: node -e 'console.log(v8.getHeapStatistics()) ; console.log(v8.getHeapStatistics())'
working-directory: ${{ runner.temp }}/example
if: ${{ matrix.server != 'cloud' || env.TEMPORAL_CLIENT_CERT != '' }}
# We write the certs to disk because it serves the sample. Written into /tmp/temporal-certs
- name: Create certs dir
shell: bash
run: node scripts/create-certs-dir.js "${{ runner.temp }}/certs"
if: ${{ matrix.server == 'cloud' && env.TEMPORAL_CLIENT_CERT != '' }}
- name: Test run a workflow (non-cloud)
run: node scripts/test-example.js --work-dir "${{ runner.temp }}/example"
shell: bash
env:
TEMPORAL_ADDRESS: localhost
TEMPORAL_NAMESPACE: default
TEMPORAL_TASK_QUEUE: ${{ format('{0}-{1}-{2}', matrix.os, matrix.node, matrix.target) }}
if: ${{ matrix.server == 'cli' }}
- name: Test run a workflow (cloud)
run: node scripts/test-example.js --work-dir "${{ runner.temp }}/example"
shell: bash
env:
# TODO: get a permanent cloud namespace for CI
# These env vars are ignored by the docker server example
TEMPORAL_ADDRESS: sdk-ci.a2dd6.tmprl.cloud
TEMPORAL_NAMESPACE: sdk-ci.a2dd6
TEMPORAL_CLIENT_CERT_PATH: ${{ runner.temp }}/certs/client.pem
TEMPORAL_CLIENT_KEY_PATH: ${{ runner.temp }}/certs/client.key
TEMPORAL_TASK_QUEUE: ${{ format('{0}-{1}-{2}', matrix.os, matrix.node, matrix.target) }}
if: ${{ matrix.server == 'cloud' && env.TEMPORAL_CLIENT_CERT != '' }}
- name: Destroy certs dir
run: rm -rf ${{ runner.temp }}/certs
shell: bash
if: ${{ matrix.server == 'cloud' && env.TEMPORAL_CLIENT_CERT != '' }}
# Runs the features repo tests with this repo's current SDK code
features-tests:
uses: temporalio/features/.github/workflows/typescript.yaml@main
with:
typescript-repo-path: ${{github.event.pull_request.head.repo.full_name}}
version: ${{github.event.pull_request.head.ref}}
version-is-repo-ref: true
stress-tests:
uses: ./.github/workflows/stress.yml
with:
test-type: ci-stress
test-timeout-minutes: 20
reuse-v8-context: false
stress-tests-reuse-context:
uses: ./.github/workflows/stress.yml
with:
test-type: ci-stress
test-timeout-minutes: 20
reuse-v8-context: true
# Run TS linting and ts-prune to find unused code
lint-and-prune:
strategy:
# Using a matrix here ensure that Rust-related actions below can be easily be copied from the
# compile-binairies job and that the Rust build cache will be usable
matrix:
include:
- os: ubuntu
runner: ubuntu-22.04
target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 16
- name: Get NPM cache directory
id: npm-cache-dir
shell: bash
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
- name: Restore NPM cache
uses: actions/cache/restore@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: npm-main-${{ runner.os }}-${{ hashFiles('./package-lock.json') }}
restore-keys: |
npm-main-${{ runner.os }}-
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
target: ${{ matrix.target }}
- name: Install protoc
uses: arduino/setup-protoc@v1
with:
version: '3.x'
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Rust Cargo and Build cache
uses: Swatinem/rust-cache@v2
with:
workspaces: packages/core-bridge -> target
prefix-key: corebridge-buildcache
shared-key: ${{ matrix.target }}
env-vars: ''
save-if: false
- name: Download dependencies
run: |
npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose
# eslint-import-resolver-typescript requires packages to be built
- name: Compile all non-rust code
run: npm run build -- --ignore @temporalio/core-bridge
- run: npm run lint.check
- run: npm run lint.prune
build-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 16
- name: Get NPM cache directory
id: npm-cache-dir
shell: bash
run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT}
- name: Restore NPM cache
uses: actions/cache/restore@v3
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: npm-main-${{ runner.os }}-${{ hashFiles('./package-lock.json') }}
restore-keys: |
npm-main-${{ runner.os }}-
# Don't build during install phase since we're going to explicitly build
- name: Download dependencies
run: |
npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose || npm ci --ignore-scripts --verbose
- run: npm run build -- --ignore @temporalio/core-bridge
# Do docs stuff (only on one host)
- name: Build docs
run: npm run docs
env:
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
- name: Deploy prod docs # TODO: only deploy prod docs when we publish a new version
if: ${{ github.ref == 'refs/heads/main' }}
run: npx vercel deploy packages/docs/build -t ${{ secrets.VERCEL_TOKEN }} --name typescript --scope temporal --prod --yes
- name: Deploy draft docs
# Don't run on forks, since secrets won't be available, and command will fail
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.ref != 'refs/heads/main' }}
run: npx vercel deploy packages/docs/build -t ${{ secrets.VERCEL_TOKEN }} --name typescript --scope temporal --yes