44 push :
55 tags :
66 - ' v*'
7+ workflow_dispatch :
8+ inputs :
9+ version :
10+ description : ' Release version (e.g., 1.2.3 or 1.3.0-rc.1). Do NOT include the "v" prefix.'
11+ required : true
12+ type : string
13+ dry_run :
14+ description : ' Dry run — build and validate without publishing'
15+ required : false
16+ type : boolean
17+ default : false
718
819permissions :
920 contents : write
@@ -12,11 +23,51 @@ jobs:
1223 release :
1324 runs-on : macos-latest
1425 steps :
26+ - name : Validate version format
27+ if : github.event_name == 'workflow_dispatch'
28+ env :
29+ INPUT_VERSION : ${{ inputs.version }}
30+ run : |
31+ if [[ ! "$INPUT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
32+ echo "::error::Invalid version format: '$INPUT_VERSION'. Expected semver (e.g., 1.2.3 or 1.3.0-rc.1)"
33+ exit 1
34+ fi
35+
36+ - name : Resolve version
37+ id : version
38+ env :
39+ INPUT_VERSION : ${{ inputs.version }}
40+ EVENT_NAME : ${{ github.event_name }}
41+ run : |
42+ if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
43+ echo "VERSION=v${INPUT_VERSION}" >> "$GITHUB_OUTPUT"
44+ else
45+ echo "VERSION=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
46+ fi
47+
1548 - name : Checkout
1649 uses : actions/checkout@v4
1750 with :
1851 fetch-depth : 0
1952
53+ - name : Check tag does not already exist
54+ if : github.event_name == 'workflow_dispatch'
55+ env :
56+ TAG : ${{ steps.version.outputs.VERSION }}
57+ run : |
58+ if git rev-parse "$TAG" >/dev/null 2>&1; then
59+ echo "::error::Tag $TAG already exists"
60+ exit 1
61+ fi
62+
63+ - name : Create tag
64+ if : github.event_name == 'workflow_dispatch' && !inputs.dry_run
65+ env :
66+ TAG : ${{ steps.version.outputs.VERSION }}
67+ run : |
68+ git tag "$TAG"
69+ git push origin "$TAG"
70+
2071 - name : Set up Go
2172 uses : actions/setup-go@v5
2273 with :
@@ -30,20 +81,22 @@ jobs:
3081 with :
3182 distribution : goreleaser
3283 version : latest
33- args : release --clean
84+ args : release --clean ${{ (github.event_name == 'workflow_dispatch' && inputs.dry_run) && '--snapshot' || '' }}
3485 env :
3586 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
36-
37- - name : Extract version from tag
38- id : version
39- run : echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
87+ GORELEASER_CURRENT_TAG : ${{ steps.version.outputs.VERSION }}
4088
4189 - name : Create DMG files
42- run : ./scripts/create-dmg.sh ${{ steps.version.outputs.VERSION }}
90+ if : ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }}
91+ env :
92+ TAG : ${{ steps.version.outputs.VERSION }}
93+ run : ./scripts/create-dmg.sh "$TAG"
4394
4495 - name : Upload DMG to release
96+ if : ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }}
4597 uses : softprops/action-gh-release@v2
4698 with :
99+ tag_name : ${{ steps.version.outputs.VERSION }}
47100 files : |
48101 dist/*.dmg
49102 env :
0 commit comments