| ... | @@ -4,6 +4,12 @@ on: | ... | @@ -4,6 +4,12 @@ on: |
| 4 | push: | 4 | push: |
| 5 | tags: | 5 | tags: |
| 6 | - "v*.*.*" | 6 | - "v*.*.*" |
| | 7 | workflow_dispatch: |
| | 8 | inputs: |
| | 9 | version: |
| | 10 | description: "Release version (for example 1.2.3 or v1.2.3)" |
| | 11 | required: true |
| | 12 | type: string |
| 7 | | 13 | |
| 8 | permissions: | 14 | permissions: |
| 9 | contents: write | 15 | contents: write |
| ... | @@ -14,10 +20,33 @@ jobs: | ... | @@ -14,10 +20,33 @@ jobs: |
| 14 | name: Preflight | 20 | name: Preflight |
| 15 | runs-on: ubuntu-24.04 | 21 | runs-on: ubuntu-24.04 |
| 16 | outputs: | 22 | outputs: |
| 17 | version: ${{ steps.version.outputs.value }} | 23 | version: ${{ steps.release_meta.outputs.version }} |
| | 24 | tag: ${{ steps.release_meta.outputs.tag }} |
| | 25 | ref: ${{ steps.release_ref.outputs.value }} |
| 18 | steps: | 26 | steps: |
| 19 | - name: Checkout | 27 | - name: Checkout |
| 20 | uses: actions/checkout@v4 | 28 | uses: actions/checkout@v4 |
| | 29 | with: |
| | 30 | fetch-depth: 0 |
| | 31 | |
| | 32 | - id: release_meta |
| | 33 | name: Resolve release version |
| | 34 | shell: bash |
| | 35 | run: | |
| | 36 | if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then |
| | 37 | raw="${{ github.event.inputs.version }}" |
| | 38 | else |
| | 39 | raw="${GITHUB_REF_NAME}" |
| | 40 | fi |
| | 41 | |
| | 42 | version="${raw#v}" |
| | 43 | if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then |
| | 44 | echo "Invalid release version: $raw" >&2 |
| | 45 | exit 1 |
| | 46 | fi |
| | 47 | |
| | 48 | echo "version=$version" >> "$GITHUB_OUTPUT" |
| | 49 | echo "tag=v$version" >> "$GITHUB_OUTPUT" |
| 21 | | 50 | |
| 22 | - name: Setup Bun | 51 | - name: Setup Bun |
| 23 | uses: oven-sh/setup-bun@v2 | 52 | uses: oven-sh/setup-bun@v2 |
| ... | @@ -29,6 +58,65 @@ jobs: | ... | @@ -29,6 +58,65 @@ jobs: |
| 29 | with: | 58 | with: |
| 30 | node-version-file: package.json | 59 | node-version-file: package.json |
| 31 | | 60 | |
| | 61 | - name: Update version strings |
| | 62 | if: github.event_name == 'workflow_dispatch' |
| | 63 | env: |
| | 64 | RELEASE_VERSION: ${{ steps.release_meta.outputs.version }} |
| | 65 | run: | |
| | 66 | node --input-type=module -e ' |
| | 67 | import { readFileSync, writeFileSync } from "node:fs"; |
| | 68 | |
| | 69 | const files = [ |
| | 70 | "apps/server/package.json", |
| | 71 | "apps/desktop/package.json", |
| | 72 | "apps/web/package.json", |
| | 73 | "packages/contracts/package.json", |
| | 74 | ]; |
| | 75 | |
| | 76 | for (const file of files) { |
| | 77 | const packageJson = JSON.parse(readFileSync(file, "utf8")); |
| | 78 | packageJson.version = process.env.RELEASE_VERSION; |
| | 79 | writeFileSync(file, `${JSON.stringify(packageJson, null, 2)}\n`); |
| | 80 | } |
| | 81 | ' |
| | 82 | |
| | 83 | - name: Refresh lockfile |
| | 84 | if: github.event_name == 'workflow_dispatch' |
| | 85 | run: bun install |
| | 86 | |
| | 87 | - name: Commit and push release version + tag |
| | 88 | if: github.event_name == 'workflow_dispatch' |
| | 89 | shell: bash |
| | 90 | env: |
| | 91 | RELEASE_TAG: ${{ steps.release_meta.outputs.tag }} |
| | 92 | run: | |
| | 93 | if git ls-remote --exit-code --tags origin "$RELEASE_TAG" >/dev/null 2>&1; then |
| | 94 | echo "Tag $RELEASE_TAG already exists on origin." >&2 |
| | 95 | exit 1 |
| | 96 | fi |
| | 97 | |
| | 98 | git config user.name "github-actions[bot]" |
| | 99 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" |
| | 100 | |
| | 101 | if ! git diff --quiet -- apps/server/package.json apps/desktop/package.json apps/web/package.json packages/contracts/package.json bun.lock; then |
| | 102 | git add apps/server/package.json apps/desktop/package.json apps/web/package.json packages/contracts/package.json bun.lock |
| | 103 | git commit -m "chore(release): prepare $RELEASE_TAG" -m "Co-authored-by: codex <codex@users.noreply.github.com>" |
| | 104 | fi |
| | 105 | |
| | 106 | git tag "$RELEASE_TAG" |
| | 107 | git push origin "HEAD:${GITHUB_REF_NAME}" |
| | 108 | git push origin "refs/tags/$RELEASE_TAG" |
| | 109 | |
| | 110 | - id: release_ref |
| | 111 | name: Resolve source ref |
| | 112 | shell: bash |
| | 113 | run: | |
| | 114 | if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then |
| | 115 | echo "value=refs/tags/${{ steps.release_meta.outputs.tag }}" >> "$GITHUB_OUTPUT" |
| | 116 | else |
| | 117 | echo "value=${GITHUB_SHA}" >> "$GITHUB_OUTPUT" |
| | 118 | fi |
| | 119 | |
| 32 | - name: Install dependencies | 120 | - name: Install dependencies |
| 33 | run: bun install --frozen-lockfile | 121 | run: bun install --frozen-lockfile |
| 34 | | 122 | |
| ... | @@ -41,10 +129,6 @@ jobs: | ... | @@ -41,10 +129,6 @@ jobs: |
| 41 | - name: Test | 129 | - name: Test |
| 42 | run: bun run test | 130 | run: bun run test |
| 43 | | 131 | |
| 44 | - id: version | | |
| 45 | name: Resolve release version | | |
| 46 | run: echo "value=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" | | |
| 47 | | | |
| 48 | build: | 132 | build: |
| 49 | name: Build ${{ matrix.label }} | 133 | name: Build ${{ matrix.label }} |
| 50 | needs: preflight | 134 | needs: preflight |
| ... | @@ -76,6 +160,9 @@ jobs: | ... | @@ -76,6 +160,9 @@ jobs: |
| 76 | steps: | 160 | steps: |
| 77 | - name: Checkout | 161 | - name: Checkout |
| 78 | uses: actions/checkout@v4 | 162 | uses: actions/checkout@v4 |
| | 163 | with: |
| | 164 | ref: ${{ needs.preflight.outputs.ref }} |
| | 165 | fetch-depth: 0 |
| 79 | | 166 | |
| 80 | - name: Setup Bun | 167 | - name: Setup Bun |
| 81 | uses: oven-sh/setup-bun@v2 | 168 | uses: oven-sh/setup-bun@v2 |
| ... | @@ -215,7 +302,7 @@ jobs: | ... | @@ -215,7 +302,7 @@ jobs: |
| 215 | - name: Publish release | 302 | - name: Publish release |
| 216 | uses: softprops/action-gh-release@v2 | 303 | uses: softprops/action-gh-release@v2 |
| 217 | with: | 304 | with: |
| 218 | tag_name: ${{ github.ref_name }} | 305 | tag_name: ${{ needs.preflight.outputs.tag }} |
| 219 | name: T3 Code v${{ needs.preflight.outputs.version }} | 306 | name: T3 Code v${{ needs.preflight.outputs.version }} |
| 220 | generate_release_notes: true | 307 | generate_release_notes: true |
| 221 | files: release-assets/* | 308 | files: release-assets/* |