Release #2646
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: | |
| schedule: | |
| - cron: '0 9 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| web: | |
| description: 'Release Web?' | |
| required: true | |
| type: boolean | |
| default: false | |
| desktop_macos: | |
| description: 'Desktop - macOS' | |
| required: true | |
| type: boolean | |
| default: false | |
| desktop_windows: | |
| description: 'Desktop - Windows' | |
| required: true | |
| type: boolean | |
| default: false | |
| desktop_linux: | |
| description: 'Desktop - Linux' | |
| required: true | |
| type: boolean | |
| default: false | |
| mobile: | |
| description: 'Release Mobile?' | |
| required: true | |
| type: boolean | |
| default: false | |
| ios-app-version: | |
| description: 'iOS App Store Version (Optional, use tag version if empty)' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| actions: write | |
| id-token: write | |
| packages: write | |
| security-events: write | |
| attestations: write | |
| issues: write | |
| jobs: | |
| prepare: | |
| name: Prepare | |
| runs-on: ubuntu-latest | |
| outputs: | |
| APP_VERSION: ${{ steps.prepare.outputs.APP_VERSION }} | |
| GIT_SHORT_HASH: ${{ steps.prepare.outputs.GIT_SHORT_HASH }} | |
| BUILD_TYPE: ${{ steps.prepare.outputs.BUILD_TYPE }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Prepare Release | |
| id: prepare | |
| uses: ./.github/actions/prepare-release | |
| canary-gate: | |
| name: Canary Gate | |
| runs-on: ubuntu-latest | |
| needs: | |
| - prepare | |
| outputs: | |
| SHOULD_RELEASE: ${{ steps.decide.outputs.SHOULD_RELEASE }} | |
| LAST_CANARY_TAG: ${{ steps.decide.outputs.LAST_CANARY_TAG }} | |
| LAST_CANARY_SHA: ${{ steps.decide.outputs.LAST_CANARY_SHA }} | |
| steps: | |
| - name: Decide whether to release | |
| id: decide | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const buildType = '${{ needs.prepare.outputs.BUILD_TYPE }}' | |
| if (buildType !== 'canary') { | |
| core.setOutput('SHOULD_RELEASE', 'true') | |
| return | |
| } | |
| const owner = context.repo.owner | |
| const repo = context.repo.repo | |
| const currentSha = context.sha | |
| const canaryTagRe = /^v\d+\.\d+\.\d+-canary\.[0-9a-f]+$/i | |
| let page = 1 | |
| const perPage = 100 | |
| let lastCanary = null | |
| while (!lastCanary && page <= 10) { | |
| const { data } = await github.rest.repos.listTags({ | |
| owner, | |
| repo, | |
| per_page: perPage, | |
| page, | |
| }) | |
| for (const tag of data) { | |
| if (canaryTagRe.test(tag.name)) { | |
| lastCanary = tag | |
| break | |
| } | |
| } | |
| if (data.length < perPage) break | |
| page++ | |
| } | |
| if (!lastCanary) { | |
| core.warning('No canary tags found; proceeding with canary release.') | |
| core.setOutput('SHOULD_RELEASE', 'true') | |
| return | |
| } | |
| core.setOutput('LAST_CANARY_TAG', lastCanary.name) | |
| core.setOutput('LAST_CANARY_SHA', lastCanary.commit.sha) | |
| const shouldRelease = lastCanary.commit.sha !== currentSha | |
| core.info(`Latest canary tag ${lastCanary.name} -> ${lastCanary.commit.sha}; current ${currentSha}; should_release=${shouldRelease}`) | |
| core.setOutput('SHOULD_RELEASE', shouldRelease ? 'true' : 'false') | |
| cloud: | |
| name: Release Cloud | |
| if: ${{ inputs.web || github.event_name != 'workflow_dispatch' }} | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/release-cloud.yml | |
| secrets: inherit | |
| with: | |
| build-type: ${{ needs.prepare.outputs.BUILD_TYPE }} | |
| app-version: ${{ needs.prepare.outputs.APP_VERSION }} | |
| git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }} | |
| image: | |
| name: Release Docker Image | |
| if: ${{ needs.canary-gate.outputs.SHOULD_RELEASE == 'true' }} | |
| runs-on: ubuntu-latest | |
| needs: | |
| - prepare | |
| - canary-gate | |
| - cloud | |
| steps: | |
| - uses: trstringer/manual-approval@v1 | |
| if: ${{ needs.prepare.outputs.BUILD_TYPE == 'stable' }} | |
| name: Wait for approval | |
| with: | |
| secret: ${{ secrets.GITHUB_TOKEN }} | |
| approvers: darkskygit | |
| minimum-approvals: 1 | |
| fail-on-denial: true | |
| issue-title: Please confirm to release docker image | |
| issue-body: | | |
| Env: ${{ needs.prepare.outputs.BUILD_TYPE }} | |
| Candidate: ghcr.io/toeverything/affine:${{ needs.prepare.outputs.BUILD_TYPE }}-${{ needs.prepare.outputs.GIT_SHORT_HASH }} | |
| Tag: ghcr.io/toeverything/affine:${{ needs.prepare.outputs.BUILD_TYPE }} | |
| > comment with "approve", "approved", "lgtm", "yes" to approve | |
| > comment with "deny", "denied", "no" to deny | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| logout: false | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Tag Image | |
| run: | | |
| docker buildx imagetools create --tag ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}} ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}}-${{needs.prepare.outputs.GIT_SHORT_HASH}} | |
| docker buildx imagetools create --tag ghcr.io/toeverything/affine:${{needs.prepare.outputs.APP_VERSION}} ghcr.io/toeverything/affine:${{needs.prepare.outputs.BUILD_TYPE}}-${{needs.prepare.outputs.GIT_SHORT_HASH}} | |
| desktop: | |
| name: Release Desktop | |
| if: >- | |
| ${{ | |
| (github.event_name != 'workflow_dispatch' && needs.canary-gate.outputs.SHOULD_RELEASE == 'true') || | |
| inputs.desktop_macos || | |
| inputs.desktop_windows || | |
| inputs.desktop_linux | |
| }} | |
| needs: | |
| - prepare | |
| - canary-gate | |
| uses: ./.github/workflows/release-desktop.yml | |
| secrets: inherit | |
| with: | |
| build-type: ${{ needs.prepare.outputs.BUILD_TYPE }} | |
| app-version: ${{ needs.prepare.outputs.APP_VERSION }} | |
| git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }} | |
| desktop_macos: ${{ github.event_name != 'workflow_dispatch' || inputs.desktop_macos }} | |
| desktop_windows: ${{ github.event_name != 'workflow_dispatch' || inputs.desktop_windows }} | |
| desktop_linux: ${{ github.event_name != 'workflow_dispatch' || inputs.desktop_linux }} | |
| require-windows-signing: ${{ needs.prepare.outputs.BUILD_TYPE == 'stable' || (github.event_name == 'workflow_dispatch' && inputs.desktop_windows) }} | |
| mobile: | |
| name: Release Mobile | |
| if: ${{ inputs.mobile }} | |
| needs: | |
| - prepare | |
| uses: ./.github/workflows/release-mobile.yml | |
| secrets: inherit | |
| with: | |
| build-type: ${{ needs.prepare.outputs.BUILD_TYPE }} | |
| app-version: ${{ needs.prepare.outputs.APP_VERSION }} | |
| git-short-hash: ${{ needs.prepare.outputs.GIT_SHORT_HASH }} | |
| ios-app-version: ${{ inputs.ios-app-version }} |