Repository navigation
Publish #28
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: Publish | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: Release type | |
| type: choice | |
| required: true | |
| default: patch | |
| options: | |
| - patch | |
| - minor | |
| - major | |
| - prepatch | |
| - preminor | |
| - premajor | |
| - prerelease | |
| dry_run: | |
| description: Dry run (build everything and run `npm publish --dry-run`, but don't publish, commit, tag or create a release) | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: publish-${{ github.workflow }} | |
| cancel-in-progress: false | |
| jobs: | |
| build-windows: | |
| name: Build Windows tool (${{ matrix.arch }}) | |
| # SwiftPM builds macro tools only for the host, so each architecture builds on a runner of its own. | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 30 | |
| strategy: | |
| matrix: | |
| include: | |
| - arch: x64 | |
| runner: windows-latest | |
| build_arch: amd64 | |
| - arch: arm64 | |
| runner: windows-11-arm | |
| build_arch: arm64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| - name: Install Swift | |
| uses: compnerd/gha-setup-swift@bbae8ce86bac5a3449f3992b3d88bc4ca25f2057 # v0.5.0 | |
| with: | |
| swift-version: swift-6.4.0-release | |
| swift-build: 6.4.0-RELEASE | |
| build_arch: ${{ matrix.build_arch }} | |
| - name: Setup Node | |
| uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | |
| with: | |
| node-version: 24 | |
| - name: Build release tool | |
| # Runs scripts/build.js: builds the release plugin binary for this architecture as | |
| # platforms/win32-<arch>/ExpoModulesMacros.exe. | |
| run: npm run build | |
| - name: Upload tool | |
| uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 | |
| with: | |
| # Named after the package directory: the publish job downloads every artifact into | |
| # `platforms/`, and each one lands in a directory of its name. | |
| name: win32-${{ matrix.arch }} | |
| path: platforms/win32-${{ matrix.arch }}/ExpoModulesMacros.exe | |
| if-no-files-found: error | |
| publish: | |
| name: Build and publish to npm | |
| needs: build-windows | |
| # Builds the native macOS tool binary, so it must run on macOS. The Windows binaries come from the | |
| # build-windows jobs. | |
| # The package declares swift-tools-version 6.2, which requires Xcode 26+. | |
| runs-on: macos-26 | |
| permissions: | |
| # Required for npm trusted publishing (OIDC) and provenance. | |
| id-token: write | |
| # Required to push the version bump commit/tag and create the release. | |
| contents: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 | |
| with: | |
| # The default token lets gh create the release and push the bump | |
| # commit/tag. Note: commits pushed with GITHUB_TOKEN do NOT trigger | |
| # other workflows (e.g. the Swift CI), by GitHub's design. | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Node | |
| uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - name: Update npm | |
| # Trusted publishing requires npm >= 11.5.1. | |
| run: npm install -g npm@latest | |
| - name: Configure git | |
| run: | | |
| git config user.name "expo-bot" | |
| git config user.email "expo-bot@users.noreply.github.com" | |
| - name: Bump version | |
| id: bump | |
| # Only edit package.json here; the commit, tag and release are created | |
| # at the end so a failed build/publish leaves the branch untouched. | |
| run: | | |
| version=$(npm version "${{ inputs.release_type }}" --no-git-tag-version) | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "Bumping to $version" | |
| # npm 11 doesn't publish a prerelease version (one with a hyphen) without a dist-tag, and | |
| # it must not become `latest` anyway. | |
| case "$version" in | |
| *-*) tag=next ;; | |
| *) tag=latest ;; | |
| esac | |
| echo "tag=$tag" >> "$GITHUB_OUTPUT" | |
| echo "Publishing with the dist-tag $tag" | |
| # The platform packages get the same version, and `expo-modules-macros` lists them as | |
| # optional dependencies with that exact version. | |
| node scripts/set-platform-versions.js | |
| - name: Select Xcode | |
| # Pin to an Xcode that ships Swift 6.2 (required by Package.swift). | |
| run: sudo xcode-select -switch /Applications/Xcode_26.4.1.app | |
| - name: Cache SwiftPM build | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: apple/.build | |
| key: spm-${{ github.repository }}-${{ runner.os }}-${{ hashFiles('apple/Package.resolved') }} | |
| restore-keys: | | |
| spm-${{ github.repository }}-${{ runner.os }}- | |
| - name: Resolve dependencies | |
| run: swift package resolve | |
| working-directory: apple | |
| - name: Install dependencies | |
| # The wrapper's `prepublishOnly` build needs `tsc`; the tool binary needs none. | |
| run: npm install | |
| - name: Build release tool | |
| # Runs scripts/build.js: builds the release plugin binary, | |
| # copies it to apple/ExpoModulesMacros, and strips it. | |
| run: npm run build | |
| - name: Download Windows tools | |
| # Each artifact goes into the directory of its name: `platforms/win32-<arch>`. | |
| uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 | |
| with: | |
| pattern: win32-* | |
| path: platforms | |
| - name: Verify Windows tools | |
| run: ls -l platforms/win32-x64/ExpoModulesMacros.exe platforms/win32-arm64/ExpoModulesMacros.exe | |
| - name: Publish the Windows packages | |
| # Published before `expo-modules-macros`, whose optional dependencies point at them, so that | |
| # package is never on npm without them. Each package needs trusted publishing (OIDC) | |
| # configured on npmjs.com for this workflow. | |
| env: | |
| DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }} | |
| run: | | |
| for arch in x64 arm64; do | |
| npm publish --access public --tag "${{ steps.bump.outputs.tag }}" $DRY_RUN "./platforms/win32-$arch" | |
| done | |
| - name: Publish | |
| # Authentication is handled via OIDC trusted publishing — no token needed. | |
| # npm generates provenance automatically when publishing via OIDC. | |
| env: | |
| DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }} | |
| run: npm publish --access public --tag "${{ steps.bump.outputs.tag }}" $DRY_RUN | |
| # Everything below only runs once the publish above has succeeded, and not in a dry run. | |
| - name: Commit, tag and push | |
| if: ${{ !inputs.dry_run }} | |
| run: | | |
| version="${{ steps.bump.outputs.version }}" | |
| git commit -am "Release $version" | |
| # Use an annotated tag so `git push --follow-tags` actually pushes it | |
| # (--follow-tags ignores lightweight tags). | |
| git tag -a "$version" -m "Release $version" | |
| git push --follow-tags origin HEAD | |
| - name: Create GitHub release | |
| if: ${{ !inputs.dry_run }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Tag prerelease versions (those containing a hyphen) as prereleases. | |
| run: | | |
| version="${{ steps.bump.outputs.version }}" | |
| prerelease="" | |
| case "$version" in | |
| *-*) prerelease="--prerelease" ;; | |
| esac | |
| gh release create "$version" \ | |
| --title "$version" \ | |
| --generate-notes \ | |
| $prerelease |