Repository navigation
fix(ios): do not prompt Face ID on isCredentialsSaved #85
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 PR beta package | |
| on: | |
| issue_comment: | |
| types: | |
| - created | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: Pull request number to publish | |
| required: true | |
| type: number | |
| concurrency: | |
| group: pr-beta-${{ github.event.issue.number || inputs.pr_number }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| id-token: write | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| publish: | |
| if: ${{ github.event_name == 'workflow_dispatch' || (github.event.issue.pull_request && contains(github.event.comment.body, '/publish-beta')) }} | |
| runs-on: ubuntu-latest | |
| # Keep this job capped at 10 minutes; never raise it unless explicitly asked. | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Resolve PR and access checks | |
| id: pr | |
| uses: actions/github-script@v9.0.0 | |
| with: | |
| script: | | |
| const prNumber = context.eventName === 'workflow_dispatch' | |
| ? Number(core.getInput('pr_number')) | |
| : context.payload.issue.number; | |
| const { owner, repo } = context.repo; | |
| const { data: pr } = await github.rest.pulls.get({ | |
| owner, | |
| repo, | |
| pull_number: prNumber, | |
| }); | |
| const actor = context.eventName === 'issue_comment' | |
| ? context.payload.comment.user.login | |
| : context.actor; | |
| core.setOutput('actor', actor); | |
| core.setOutput('pr_number', String(prNumber)); | |
| if (pr.state !== 'open') { | |
| core.setFailed(`PR #${prNumber} is not open.`); | |
| return; | |
| } | |
| if (pr.head.repo.full_name !== `${owner}/${repo}`) { | |
| core.setFailed('Fork PRs cannot publish beta packages because the workflow needs repository secrets.'); | |
| return; | |
| } | |
| if (context.eventName === 'issue_comment') { | |
| const actor = context.payload.comment.user.login; | |
| const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({ | |
| owner, | |
| repo, | |
| username: actor, | |
| }); | |
| const allowed = ['admin', 'maintain', 'write'].includes(permission.permission); | |
| if (!allowed) { | |
| core.setFailed(`@${actor} does not have permission to publish beta packages.`); | |
| return; | |
| } | |
| } | |
| const prState = await github.graphql( | |
| `query($owner: String!, $repo: String!, $prNumber: Int!) { | |
| repository(owner: $owner, name: $repo) { | |
| pullRequest(number: $prNumber) { | |
| commits(last: 1) { | |
| nodes { | |
| commit { | |
| statusCheckRollup { | |
| state | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }`, | |
| { | |
| owner, | |
| repo, | |
| prNumber, | |
| }, | |
| ); | |
| const rollupState = prState.repository.pullRequest.commits.nodes[0]?.commit.statusCheckRollup?.state ?? 'PENDING'; | |
| if (rollupState !== 'SUCCESS') { | |
| core.setFailed(`PR checks are not green yet (current state: ${rollupState}).`); | |
| return; | |
| } | |
| core.setOutput('head_sha', pr.head.sha); | |
| - name: Mark publish as running | |
| uses: actions/github-script@v9.0.0 | |
| with: | |
| script: | | |
| const marker = '<!-- pr-beta-publish -->'; | |
| const prNumber = Number('${{ steps.pr.outputs.pr_number }}'); | |
| const actor = '${{ steps.pr.outputs.actor }}'; | |
| const body = [ | |
| marker, | |
| '', | |
| '## Beta npm build', | |
| '', | |
| 'Status: publishing', | |
| '', | |
| `Requested by @${actor}.`, | |
| '', | |
| `This run will publish the PR head to the \`beta\` npm tag.`, | |
| '', | |
| `Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, | |
| ].join('\n'); | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find((comment) => comment.user.type === 'Bot' && comment.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| return; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body, | |
| }); | |
| - name: Check out PR head | |
| uses: actions/checkout@v6.0.2 | |
| with: | |
| ref: ${{ steps.pr.outputs.head_sha }} | |
| fetch-depth: 0 | |
| filter: blob:none | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2.2.0 | |
| - name: Install dependencies | |
| run: bun i | |
| - name: Check plugin wiring | |
| run: bun run check:wiring | |
| - name: Set beta package version | |
| id: version | |
| env: | |
| PR_NUMBER: ${{ steps.pr.outputs.pr_number }} | |
| run: | | |
| node <<'NODE' >> "$GITHUB_OUTPUT" | |
| const fs = require('fs'); | |
| const path = 'package.json'; | |
| const pkg = JSON.parse(fs.readFileSync(path, 'utf8')); | |
| const baseVersion = pkg.version.split('-')[0]; | |
| const prNumber = process.env.PR_NUMBER; | |
| const runNumber = process.env.GITHUB_RUN_NUMBER; | |
| const runAttempt = process.env.GITHUB_RUN_ATTEMPT; | |
| const betaVersion = `${baseVersion}-beta.pr${prNumber}.${runNumber}.${runAttempt}`; | |
| pkg.version = betaVersion; | |
| fs.writeFileSync(path, `${JSON.stringify(pkg, null, 2)}\n`); | |
| console.log(`package_name=${pkg.name}`); | |
| console.log(`version=${betaVersion}`); | |
| NODE | |
| - name: Build | |
| run: bun run build | |
| - name: Setup Node.js for npm publish | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: 24.x | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install npm CLI for staged publishing | |
| run: npm install -g npm@^11.15.0 | |
| - name: Stage publish to npm beta | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| npm --version | |
| npm stage publish --tag beta --provenance --access public --ignore-scripts | |
| - name: Request stage approval | |
| continue-on-error: true | |
| env: | |
| GH_TOKEN: ${{ secrets.NPM_STAGE_DISPATCH_TOKEN }} | |
| run: | | |
| gh api --method POST repos/Cap-go/automations/dispatches \ | |
| -f event_type=npm-stage-approve \ | |
| -f "client_payload[repository]=${GITHUB_REPOSITORY}" \ | |
| -f "client_payload[run_id]=${GITHUB_RUN_ID}" \ | |
| -f "client_payload[package]=${{ steps.version.outputs.package_name }}" | |
| - name: Publish success comment | |
| if: ${{ success() }} | |
| uses: actions/github-script@v9.0.0 | |
| with: | |
| script: | | |
| const marker = '<!-- pr-beta-publish -->'; | |
| const prNumber = Number('${{ steps.pr.outputs.pr_number }}'); | |
| const actor = '${{ steps.pr.outputs.actor }}'; | |
| const packageName = '${{ steps.version.outputs.package_name }}'; | |
| const version = '${{ steps.version.outputs.version }}'; | |
| const shortSha = '${{ steps.pr.outputs.head_sha }}'.slice(0, 7); | |
| const body = [ | |
| marker, | |
| '', | |
| '## Beta npm build', | |
| '', | |
| 'Status: staged', | |
| '', | |
| `Version: \`${version}\``, | |
| `Source: \`${shortSha}\``, | |
| `Requested by @${actor}`, | |
| '', | |
| 'Latest beta:', | |
| '```sh', | |
| `bun add ${packageName}@beta`, | |
| `bun add ${packageName}@${version}`, | |
| '```', | |
| '', | |
| `Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, | |
| ].join('\n'); | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find((comment) => comment.user.type === 'Bot' && comment.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| return; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body, | |
| }); | |
| - name: Publish failure comment | |
| if: ${{ failure() && steps.pr.outputs.pr_number != '' }} | |
| uses: actions/github-script@v9.0.0 | |
| with: | |
| script: | | |
| const marker = '<!-- pr-beta-publish -->'; | |
| const prNumber = Number('${{ steps.pr.outputs.pr_number }}'); | |
| const body = [ | |
| marker, | |
| '', | |
| '## Beta npm build', | |
| '', | |
| 'Status: failed', | |
| '', | |
| 'Open the run for details:', | |
| `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, | |
| ].join('\n'); | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find((comment) => comment.user.type === 'Bot' && comment.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| return; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body, | |
| }); |