Release #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: 'Release type (patch, minor, major, or a semver version)' | |
| required: false | |
| type: string | |
| npm_tag: | |
| description: 'Optional npm dist-tag override (e.g. latest, v0-latest, v1-latest)' | |
| required: false | |
| type: string | |
| github_make_latest: | |
| description: 'Optional GitHub latest release override (true or false)' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Lint files | |
| run: pnpm lint | |
| - name: Test formatting | |
| run: pnpm format --check | |
| - name: Typecheck files | |
| run: pnpm typecheck | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Run tests | |
| run: pnpm test | |
| build-release: | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Build package | |
| run: pnpm package build | |
| - name: Configure Git and npm | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| printf "//registry.npmjs.org/:_authToken=%s\n" "$NPM_TOKEN" > ~/.npmrc | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Validate release type | |
| if: ${{ inputs.release_type != '' }} | |
| run: | | |
| if [[ "${{ inputs.release_type }}" =~ ^(patch|minor|major)$ ]]; then | |
| echo "Valid release type: ${{ inputs.release_type }}" | |
| elif [[ "${{ inputs.release_type }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "Valid semver version: ${{ inputs.release_type }}" | |
| else | |
| echo "Invalid input. Must be 'patch', 'minor', 'major', or a valid semver version (e.g., 1.2.3)." | |
| exit 1 | |
| fi | |
| - name: Resolve release strategy | |
| run: | | |
| branch="${{ github.ref_name }}" | |
| release_type="${{ inputs.release_type }}" | |
| npm_tag_input="${{ inputs.npm_tag }}" | |
| github_make_latest_input="${{ inputs.github_make_latest }}" | |
| package_version=$(node -p "require('./packages/react-native-boost/package.json').version") | |
| package_major="${package_version%%.*}" | |
| case "$github_make_latest_input" in | |
| ""|true|false) ;; | |
| *) | |
| echo "Invalid github_make_latest input. Must be 'true' or 'false' when provided." | |
| exit 1 | |
| ;; | |
| esac | |
| if [[ "$branch" =~ ^v([0-9]+)$ ]]; then | |
| branch_major="${BASH_REMATCH[1]}" | |
| release_npm_tag="${npm_tag_input:-v${branch_major}-latest}" | |
| release_github_make_latest="${github_make_latest_input:-false}" | |
| if [[ "$package_major" != "$branch_major" ]]; then | |
| echo "Branch $branch expects package major $branch_major, but package.json is $package_version." | |
| exit 1 | |
| fi | |
| if [[ -n "$release_type" ]]; then | |
| if [[ "$release_type" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| release_major="${release_type%%.*}" | |
| if [[ "$release_major" != "$branch_major" ]]; then | |
| echo "Explicit version $release_type does not match branch major $branch_major." | |
| exit 1 | |
| fi | |
| elif [[ "$release_type" == "major" ]]; then | |
| echo "Major increments are not allowed on maintenance branch $branch." | |
| exit 1 | |
| fi | |
| fi | |
| elif [[ "$branch" == "main" || "$branch" == "master" ]]; then | |
| release_npm_tag="${npm_tag_input:-latest}" | |
| release_github_make_latest="${github_make_latest_input:-true}" | |
| else | |
| if [[ -z "$npm_tag_input" || -z "$github_make_latest_input" ]]; then | |
| echo "Releases from branch '$branch' require explicit npm_tag and github_make_latest inputs." | |
| exit 1 | |
| fi | |
| release_npm_tag="$npm_tag_input" | |
| release_github_make_latest="$github_make_latest_input" | |
| fi | |
| if [[ ! "$release_npm_tag" =~ ^[A-Za-z0-9._-]+$ ]]; then | |
| echo "Invalid npm tag '$release_npm_tag'. Use only letters, numbers, dots, underscores, and dashes." | |
| exit 1 | |
| fi | |
| RELEASE_NPM_TAG="$release_npm_tag" node <<'NODE' | |
| const path = require('node:path'); | |
| const { createRequire } = require('node:module'); | |
| const packageRoot = path.resolve('packages/react-native-boost'); | |
| const releaseItPackageJson = require.resolve('release-it/package.json', { paths: [packageRoot] }); | |
| const requireFromReleaseIt = createRequire(releaseItPackageJson); | |
| const semver = requireFromReleaseIt('semver'); | |
| const tag = process.env.RELEASE_NPM_TAG; | |
| if (semver.validRange(tag)) { | |
| console.error(`Invalid npm tag '${tag}'. npm rejects dist-tags that parse as semver ranges.`); | |
| console.error("Use something like 'v0-latest' or 'major-v0' instead."); | |
| process.exit(1); | |
| } | |
| NODE | |
| echo "RELEASE_NPM_TAG=$release_npm_tag" >> "$GITHUB_ENV" | |
| echo "RELEASE_GITHUB_MAKE_LATEST=$release_github_make_latest" >> "$GITHUB_ENV" | |
| echo "Release branch: $branch" | |
| echo "npm tag: $release_npm_tag" | |
| echo "GitHub make_latest: $release_github_make_latest" | |
| - name: Release | |
| run: | | |
| if [ -n "${{ inputs.release_type }}" ]; then | |
| pnpm package release --increment "${{ inputs.release_type }}" --npm.tag "$RELEASE_NPM_TAG" --github.makeLatest "$RELEASE_GITHUB_MAKE_LATEST" | |
| else | |
| pnpm package release --npm.tag "$RELEASE_NPM_TAG" --github.makeLatest "$RELEASE_GITHUB_MAKE_LATEST" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} |