|
11 | 11 | permissions: {} |
12 | 12 |
|
13 | 13 | jobs: |
14 | | - release: |
15 | | - name: Release |
| 14 | + validate-release: |
| 15 | + name: Validate release |
16 | 16 | runs-on: ubuntu-latest |
17 | | - environment: release |
18 | 17 | permissions: |
19 | | - contents: write |
| 18 | + contents: read |
20 | 19 | steps: |
21 | | - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
22 | | - with: |
23 | | - persist-credentials: false |
24 | | - |
25 | | - - name: Validate version |
| 20 | + - name: Validate version and draft release |
26 | 21 | env: |
| 22 | + GH_REPO: ${{ github.repository }} |
| 23 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
27 | 24 | VERSION: ${{ inputs.version }} |
| 25 | + TAG: v${{ inputs.version }} |
28 | 26 | run: | |
29 | 27 | if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then |
30 | 28 | echo "::error::Version must match MAJOR.MINOR.PATCH (e.g., 8.1.0)" |
31 | 29 | exit 1 |
32 | 30 | fi |
33 | 31 |
|
| 32 | + RELEASE_JSON=$(gh release view "$TAG" --json isDraft,targetCommitish 2>&1) || { |
| 33 | + echo "::error::No release found for $TAG" |
| 34 | + exit 1 |
| 35 | + } |
| 36 | +
|
| 37 | + IS_DRAFT=$(echo "$RELEASE_JSON" | jq -r '.isDraft') |
| 38 | + TARGET=$(echo "$RELEASE_JSON" | jq -r '.targetCommitish') |
| 39 | +
|
| 40 | + if [[ "$IS_DRAFT" != "true" ]]; then |
| 41 | + echo "::error::Release $TAG already exists and is not a draft" |
| 42 | + exit 1 |
| 43 | + fi |
| 44 | +
|
| 45 | + if [[ "$TARGET" != "$GITHUB_SHA" ]]; then |
| 46 | + echo "::error::Draft release target ($TARGET) does not match current commit ($GITHUB_SHA)" |
| 47 | + exit 1 |
| 48 | + fi |
| 49 | +
|
| 50 | + release-gate: |
| 51 | + # N.B. This name should not change, it is used for downstream checks. |
| 52 | + name: release-gate |
| 53 | + needs: |
| 54 | + - validate-release |
| 55 | + runs-on: ubuntu-latest |
| 56 | + environment: |
| 57 | + name: release-gate |
| 58 | + steps: |
| 59 | + - run: echo "Release approved" |
| 60 | + |
| 61 | + create-deployment: |
| 62 | + name: create-deployment |
| 63 | + needs: |
| 64 | + - validate-release |
| 65 | + - release-gate |
| 66 | + runs-on: ubuntu-latest |
| 67 | + environment: |
| 68 | + name: release |
| 69 | + steps: |
| 70 | + - run: echo "Release deployment created" |
| 71 | + |
| 72 | + release: |
| 73 | + name: Release |
| 74 | + needs: |
| 75 | + - validate-release |
| 76 | + - release-gate |
| 77 | + - create-deployment |
| 78 | + runs-on: ubuntu-latest |
| 79 | + permissions: |
| 80 | + contents: write |
| 81 | + steps: |
34 | 82 | - name: Publish release |
35 | 83 | env: |
| 84 | + GH_REPO: ${{ github.repository }} |
36 | 85 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 86 | + VERSION: ${{ inputs.version }} |
37 | 87 | TAG: v${{ inputs.version }} |
38 | 88 | run: | |
| 89 | + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then |
| 90 | + echo "::error::Version must match MAJOR.MINOR.PATCH (e.g., 8.1.0)" |
| 91 | + exit 1 |
| 92 | + fi |
| 93 | +
|
39 | 94 | RELEASE_JSON=$(gh release view "$TAG" --json isDraft,targetCommitish 2>&1) || { |
40 | 95 | echo "::error::No release found for $TAG" |
41 | 96 | exit 1 |
|
0 commit comments