Skip to content

Turborepo Release

Turborepo Release #281

# Turborepo Release Pipeline
#
# This release consists of a few steps
#
# 1. Create a staging branch
# 2. Run some smoke tests on that branch
# 3. Build the Rust binary
# 4. Publish JS packages npm (including turbo itself)
# 5. Create a release branch and open a PR.
# You can opt into a dry run, which will skip publishing to npm and opening the release branch
name: Turborepo Release
env:
CARGO_PROFILE_RELEASE_LTO: true
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
RELEASE_TURBO_CLI: true # TODO: do we need this?
# Needed since we need to build on Xenial which doesn't have a new enough
# GLIBC to use Node 20.
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
on:
workflow_dispatch:
inputs:
increment:
description: "SemVer Increment (prerelease = bump canary)"
required: true
default: "prerelease"
type: choice
options:
- prerelease
- prepatch
- preminor
- premajor
- patch
- minor
- major
dry_run:
description: "Do a dry run, skipping the final publish step."
type: boolean
jobs:
stage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-node
with:
enable-corepack: false
- name: Configure git
run: |
git config --global user.name 'Turbobot'
git config --global user.email '[email protected]'
- name: Version
run: |
./scripts/version.js ${{ inputs.increment }}
cat version.txt
- name: Stage Commit
id: stage
run: cd cli && make stage-release && echo "STAGE_BRANCH=$(git branch --show-current)" >> $GITHUB_OUTPUT
- name: Show Stage Commit
run: echo "${{ steps.stage.outputs.STAGE_BRANCH }}"
outputs:
stage-branch: "${{ steps.stage.outputs.STAGE_BRANCH }}"
rust-smoke-test:
name: Rust Unit Tests
runs-on: ubuntu-latest
needs: [stage]
steps:
- name: Show Stage Commit
run: echo "${{ needs.stage.outputs.stage-branch }}"
- uses: actions/checkout@v3
with:
ref: ${{ needs.stage.outputs.stage-branch }}
- name: Setup Turborepo Environment
uses: ./.github/actions/setup-turborepo-environment
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Run Rust Unit Tests
run: cargo groups test turborepo
js-smoke-test:
name: JS Package Tests
runs-on: ubuntu-latest
needs: [stage]
steps:
- name: Show Stage Commit
run: echo "${{ needs.stage.outputs.stage-branch }}"
- uses: actions/checkout@v3
with:
ref: ${{ needs.stage.outputs.stage-branch }}
- name: Setup Turborepo Environment
uses: ./.github/actions/setup-turborepo-environment
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
node-version: "20"
- name: Install Global Turbo
uses: ./.github/actions/install-global-turbo
- name: Run JS Package Tests
run: turbo run check-types test --filter="./packages/*" --color
build-rust:
name: "Build Rust"
needs: [stage, rust-smoke-test, js-smoke-test]
strategy:
fail-fast: false
matrix:
settings:
- host: macos-latest
target: "x86_64-apple-darwin"
container-options: "--rm"
- host: macos-latest
target: "aarch64-apple-darwin"
container-options: "--rm"
- host: ubuntu-latest
container: ubuntu:xenial
container-options: "--platform=linux/amd64 --rm"
container-setup: "apt-get update && apt-get install -y curl musl-tools sudo unzip"
target: "x86_64-unknown-linux-musl"
setup: "apt-get install -y build-essential clang-5.0 lldb-5.0 llvm-5.0-dev libclang-5.0-dev"
- host: ubuntu-latest
container-options: "--rm"
target: "aarch64-unknown-linux-musl"
rust-build-env: 'CC_aarch64_unknown_linux_musl=clang AR_aarch64_unknown_linux_musl=llvm-ar RUSTFLAGS="-Clink-self-contained=yes -Clinker=rust-lld"'
setup: "sudo apt-get update && sudo apt-get install -y build-essential musl-tools clang llvm gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu"
- host: windows-latest
target: x86_64-pc-windows-msvc
container-options: "--rm"
runs-on: ${{ matrix.settings.host }}
container:
image: ${{ matrix.settings.container }}
options: ${{ matrix.settings.container-options }}
steps:
- name: Show Stage Commit
run: echo "${{ needs.stage.outputs.stage-branch }}"
- name: Checkout repo
uses: actions/checkout@v3
with:
ref: "${{ needs.stage.outputs.stage-branch }}"
- name: Setup Container
if: ${{ matrix.settings.container-setup }}
run: ${{ matrix.settings.container-setup }}
- name: Setup Protoc
uses: arduino/[email protected]
with:
version: "26.x"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup capnproto
uses: ./.github/actions/setup-capnproto
- name: Setup Rust Up
if: ${{ matrix.settings.container-setup }}
# setup-rust-toolchain uses the --retry-connrefused flag with curl to install rustup
# this flag was added in curl 7.52.0, but the Ubuntu version we use only has 7.47.0
run: |
curl --proto '=https' --tlsv1.2 --retry 10 --location --silent --show-error --fail "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y
echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH
- name: Rust Setup
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.settings.target }}
# needed to not make it override the defaults
rustflags: ""
# we want more specific settings
cache: false
- name: Build Setup
shell: bash
if: ${{ matrix.settings.setup }}
run: ${{ matrix.settings.setup }}
- name: Build
run: ${{ matrix.settings.rust-build-env }} cargo build --profile release-turborepo -p turbo --target ${{ matrix.settings.target }}
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: turbo-${{ matrix.settings.target }}
path: target/${{ matrix.settings.target }}/release-turborepo/turbo*
npm-publish:
name: "Publish To NPM"
runs-on: ubuntu-latest
needs: [stage, build-rust]
steps:
- name: Show Stage Commit
run: echo "${{ needs.stage.outputs.stage-branch }}"
- uses: actions/checkout@v3
with:
ref: "${{ needs.stage.outputs.stage-branch }}"
- run: git fetch origin --tags
- uses: ./.github/actions/setup-node
with:
enable-corepack: false
- name: Install Global Turbo
uses: ./.github/actions/install-global-turbo
- name: Configure git
run: |
git config --global user.name 'Turbobot'
git config --global user.email '[email protected]'
- name: Install GoReleaser
uses: goreleaser/goreleaser-action@v3
with:
distribution: goreleaser-pro
version: v1.18.2
install-only: true
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
- name: Download Rust artifacts
uses: actions/download-artifact@v3
with:
path: rust-artifacts
- name: Move Rust artifacts into place
run: |
mv rust-artifacts/turbo-aarch64-apple-darwin cli/dist-darwin-arm64
mv rust-artifacts/turbo-aarch64-unknown-linux-musl cli/dist-linux-arm64
cp -r rust-artifacts/turbo-x86_64-pc-windows-msvc cli/dist-windows-arm64
mv rust-artifacts/turbo-x86_64-unknown-linux-musl cli/dist-linux-amd64
mv rust-artifacts/turbo-x86_64-apple-darwin cli/dist-darwin-amd64
mv rust-artifacts/turbo-x86_64-pc-windows-msvc cli/dist-windows-amd64
- name: Perform Release
run: cd cli && make publish-turbo SKIP_PUBLISH=${{ inputs.dry_run && '--skip-publish' || '' }}
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# Upload published artifacts in case they are needed for debugging later
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: turbo-combined
path: cli/dist
create-release-pr:
name: "Open Release Branch PR"
needs: [stage, npm-publish]
runs-on: ubuntu-latest
steps:
- name: Show Stage Commit
run: echo "${{ needs.stage.outputs.stage-branch }}"
- uses: actions/[email protected]
with:
ref: ${{ needs.stage.outputs.stage-branch }}
- name: Get version
id: getVersion
run: echo "version=$(head -n 1 version.txt)" >> $GITHUB_OUTPUT
- name: Create pull request
uses: thomaseizinger/create-pull-request@master
if: ${{ !inputs.dry_run }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
head: ${{ needs.stage.outputs.stage-branch }}
base: main
title: "release(turborepo): ${{ steps.getVersion.outputs.version }}"