docs: document background click research workflow #45
Workflow file for this run
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: | |
| push: | |
| tags: | |
| - "v*" | |
| - "*.*.*" | |
| workflow_dispatch: | |
| inputs: | |
| publish_to_npm: | |
| description: "Publish the staged npm packages to npmjs.org" | |
| required: true | |
| default: false | |
| type: boolean | |
| npm_tag: | |
| description: "npm dist-tag to use when publish_to_npm is enabled" | |
| required: true | |
| default: latest | |
| type: string | |
| permissions: | |
| contents: write | |
| id-token: write | |
| jobs: | |
| package-npm: | |
| runs-on: macos-26 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd | |
| - name: Set up Node.js | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e | |
| with: | |
| node-version: "24" | |
| - name: Check npm trusted publishing CLI | |
| run: | | |
| node --version | |
| npm_version="$(npm --version)" | |
| echo "npm ${npm_version}" | |
| node -e 'const [major, minor] = process.argv[1].split(".").map(Number); if (major < 11 || (major === 11 && minor < 5)) { console.error(`npm ${process.argv[1]} is too old for trusted publishing; need 11.5.1+`); process.exit(1); }' "${npm_version}" | |
| - name: Prepare Open Computer Use signing config | |
| env: | |
| OPEN_COMPUTER_USE_CODESIGN_P12_BASE64: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_P12_BASE64 }} | |
| OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD }} | |
| OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN_PASSWORD }} | |
| OPEN_COMPUTER_USE_CODESIGN_IDENTITY: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_IDENTITY }} | |
| run: | | |
| echo "OPEN_COMPUTER_USE_CODESIGN_MODE=adhoc" >> "${GITHUB_ENV}" | |
| if [ -z "${OPEN_COMPUTER_USE_CODESIGN_P12_BASE64}" ] || [ -z "${OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD}" ]; then | |
| echo "No Open Computer Use signing certificate configured; release artifacts will fall back to ad-hoc signing and may create install-specific macOS permission identities." | |
| exit 0 | |
| fi | |
| keychain_password="${OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN_PASSWORD:-${RUNNER_TEMP}-open-computer-use-keychain}" | |
| cert_path="${RUNNER_TEMP}/open-computer-use-signing.p12" | |
| keychain_path="${RUNNER_TEMP}/open-computer-use-signing.keychain-db" | |
| CERT_PATH="${cert_path}" python3 -c 'import base64, os, pathlib; pathlib.Path(os.environ["CERT_PATH"]).write_bytes(base64.b64decode(os.environ["OPEN_COMPUTER_USE_CODESIGN_P12_BASE64"]))' | |
| security create-keychain -p "${keychain_password}" "${keychain_path}" | |
| security set-keychain-settings -lut 21600 "${keychain_path}" | |
| security unlock-keychain -p "${keychain_password}" "${keychain_path}" | |
| security import "${cert_path}" -k "${keychain_path}" -P "${OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD}" -T /usr/bin/codesign -T /usr/bin/security | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${keychain_password}" "${keychain_path}" | |
| resolved_identity="${OPEN_COMPUTER_USE_CODESIGN_IDENTITY:-}" | |
| if [ -z "${resolved_identity}" ]; then | |
| resolved_identity="$(security find-identity -v -p codesigning "${keychain_path}" | sed -n 's/.*\"\\(.*\\)\"/\\1/p' | head -n 1)" | |
| fi | |
| if [ -z "${resolved_identity}" ]; then | |
| echo "Imported signing certificate, but no usable codesigning identity was found in ${keychain_path}." >&2 | |
| exit 1 | |
| fi | |
| echo "Resolved Open Computer Use signing identity: ${resolved_identity}" | |
| { | |
| echo "OPEN_COMPUTER_USE_CODESIGN_MODE=identity" | |
| echo "OPEN_COMPUTER_USE_CODESIGN_IDENTITY=${resolved_identity}" | |
| echo "OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN=${keychain_path}" | |
| } >> "${GITHUB_ENV}" | |
| - name: Build npm release artifacts | |
| run: npm run npm:pack | |
| - name: Upload npm release artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a | |
| with: | |
| name: npm-release-artifacts | |
| path: | | |
| dist/release/npm/*.tgz | |
| dist/release/release-manifest.json | |
| if-no-files-found: error | |
| - name: Configure npm token fallback | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| if [ -n "${NPM_TOKEN}" ]; then | |
| printf '%s\n%s\n' \ | |
| "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" \ | |
| "registry=https://registry.npmjs.org/" \ | |
| > "${RUNNER_TEMP}/npm-token-fallback.npmrc" | |
| echo "NPM_CONFIG_USERCONFIG=${RUNNER_TEMP}/npm-token-fallback.npmrc" >> "${GITHUB_ENV}" | |
| echo "NODE_AUTH_TOKEN=${NPM_TOKEN}" >> "${GITHUB_ENV}" | |
| fi | |
| - name: Publish packages to npm | |
| if: ${{ github.event_name == 'push' || inputs.publish_to_npm }} | |
| env: | |
| NPM_DIST_TAG: ${{ github.event_name == 'push' && 'latest' || inputs.npm_tag }} | |
| run: | | |
| node ./scripts/npm/publish-packages.mjs \ | |
| --skip-build \ | |
| --out-dir dist/release/npm-staging \ | |
| --tag "${NPM_DIST_TAG}" | |
| release-cursor-motion-dmg: | |
| if: ${{ github.event_name == 'push' }} | |
| runs-on: macos-26 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd | |
| - name: Make DMG build script executable | |
| run: chmod +x ./scripts/build-cursor-motion-dmg.sh | |
| - name: Prepare Cursor Motion signing config | |
| env: | |
| OPEN_COMPUTER_USE_CODESIGN_P12_BASE64: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_P12_BASE64 }} | |
| OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD }} | |
| OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN_PASSWORD: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN_PASSWORD }} | |
| OPEN_COMPUTER_USE_CODESIGN_IDENTITY: ${{ secrets.OPEN_COMPUTER_USE_CODESIGN_IDENTITY }} | |
| run: | | |
| echo "CURSOR_MOTION_CODESIGN_MODE=adhoc" >> "${GITHUB_ENV}" | |
| if [ -z "${OPEN_COMPUTER_USE_CODESIGN_P12_BASE64}" ] || [ -z "${OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD}" ]; then | |
| echo "No Developer ID signing certificate configured; Cursor Motion DMG will be ad-hoc signed and notarization will be skipped." | |
| exit 0 | |
| fi | |
| keychain_password="${OPEN_COMPUTER_USE_CODESIGN_KEYCHAIN_PASSWORD:-${RUNNER_TEMP}-cursor-motion-keychain}" | |
| cert_path="${RUNNER_TEMP}/cursor-motion-signing.p12" | |
| keychain_path="${RUNNER_TEMP}/cursor-motion-signing.keychain-db" | |
| CERT_PATH="${cert_path}" python3 -c 'import base64, os, pathlib; pathlib.Path(os.environ["CERT_PATH"]).write_bytes(base64.b64decode(os.environ["OPEN_COMPUTER_USE_CODESIGN_P12_BASE64"]))' | |
| security create-keychain -p "${keychain_password}" "${keychain_path}" | |
| security set-keychain-settings -lut 21600 "${keychain_path}" | |
| security unlock-keychain -p "${keychain_password}" "${keychain_path}" | |
| security import "${cert_path}" -k "${keychain_path}" -P "${OPEN_COMPUTER_USE_CODESIGN_P12_PASSWORD}" -T /usr/bin/codesign -T /usr/bin/security | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${keychain_password}" "${keychain_path}" | |
| resolved_identity="${OPEN_COMPUTER_USE_CODESIGN_IDENTITY:-}" | |
| if [ -z "${resolved_identity}" ]; then | |
| resolved_identity="$(security find-identity -v -p codesigning "${keychain_path}" | sed -n 's/.*\"\\(.*\\)\"/\\1/p' | head -n 1)" | |
| fi | |
| if [ -z "${resolved_identity}" ]; then | |
| echo "Imported signing certificate, but no usable codesigning identity was found in ${keychain_path}." >&2 | |
| exit 1 | |
| fi | |
| { | |
| echo "CURSOR_MOTION_CODESIGN_MODE=identity" | |
| echo "CURSOR_MOTION_CODESIGN_IDENTITY=${resolved_identity}" | |
| echo "CURSOR_MOTION_CODESIGN_KEYCHAIN=${keychain_path}" | |
| } >> "${GITHUB_ENV}" | |
| - name: Build Cursor Motion DMG | |
| env: | |
| RELEASE_TAG: ${{ github.ref_name }} | |
| run: | | |
| version="${RELEASE_TAG#v}" | |
| ./scripts/build-cursor-motion-dmg.sh \ | |
| --configuration release \ | |
| --arch universal \ | |
| --version "${version}" | |
| - name: Notarize Cursor Motion DMG | |
| env: | |
| RELEASE_TAG: ${{ github.ref_name }} | |
| APPLE_NOTARY_API_KEY_P8_BASE64: ${{ secrets.APPLE_NOTARY_API_KEY_P8_BASE64 }} | |
| APPLE_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }} | |
| APPLE_NOTARY_ISSUER_ID: ${{ secrets.APPLE_NOTARY_ISSUER_ID }} | |
| APPLE_DEVELOPER_TEAM_ID: ${{ secrets.APPLE_DEVELOPER_TEAM_ID }} | |
| run: | | |
| if [ -z "${APPLE_NOTARY_API_KEY_P8_BASE64}" ] || [ -z "${APPLE_NOTARY_KEY_ID}" ] || [ -z "${APPLE_NOTARY_ISSUER_ID}" ] || [ -z "${APPLE_DEVELOPER_TEAM_ID}" ]; then | |
| echo "No notary credentials configured; skipping Cursor Motion notarization." | |
| exit 0 | |
| fi | |
| version="${RELEASE_TAG#v}" | |
| dmg_path="dist/release/cursor-motion/CursorMotion-${version}.dmg" | |
| api_key_path="${RUNNER_TEMP}/AuthKey_${APPLE_NOTARY_KEY_ID}.p8" | |
| CERT_PATH="${api_key_path}" python3 -c 'import base64, os, pathlib; pathlib.Path(os.environ["CERT_PATH"]).write_bytes(base64.b64decode(os.environ["APPLE_NOTARY_API_KEY_P8_BASE64"]))' | |
| xcrun notarytool submit "${dmg_path}" \ | |
| --key "${api_key_path}" \ | |
| --key-id "${APPLE_NOTARY_KEY_ID}" \ | |
| --issuer "${APPLE_NOTARY_ISSUER_ID}" \ | |
| --team-id "${APPLE_DEVELOPER_TEAM_ID}" \ | |
| --wait | |
| xcrun stapler staple "${dmg_path}" | |
| - name: Upload Cursor Motion release artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a | |
| with: | |
| name: cursor-motion-release-artifact | |
| path: dist/release/cursor-motion/*.dmg | |
| if-no-files-found: error | |
| - name: Publish Cursor Motion DMG to GitHub Releases | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ github.ref_name }} | |
| run: | | |
| version="${RELEASE_TAG#v}" | |
| dmg_path="dist/release/cursor-motion/CursorMotion-${version}.dmg" | |
| if gh release view "${RELEASE_TAG}" >/dev/null 2>&1; then | |
| gh release upload "${RELEASE_TAG}" "${dmg_path}" --clobber | |
| else | |
| gh release create "${RELEASE_TAG}" "${dmg_path}" \ | |
| --title "${RELEASE_TAG}" \ | |
| --generate-notes | |
| fi |