1+ name : Fix Release
2+
3+ on :
4+ workflow_dispatch :
5+ inputs :
6+ tag :
7+ description : ' Tag/version to fix (e.g., v1.2.3 or 1.2.3)'
8+ required : true
9+ type : string
10+ publish_package :
11+ description : ' Republish package to PyPI'
12+ required : true
13+ type : boolean
14+ default : true
15+ publish_container :
16+ description : ' Republish container images'
17+ required : true
18+ type : boolean
19+ default : true
20+ dry_run :
21+ description : ' Dry run mode (test without actually publishing)'
22+ required : false
23+ type : boolean
24+ default : false
25+
26+ permissions :
27+ contents : read
28+ packages : write
29+ id-token : write
30+
31+ jobs :
32+ validate-inputs :
33+ runs-on : ubuntu-latest
34+ outputs :
35+ normalized_tag : ${{ steps.normalize.outputs.tag }}
36+ steps :
37+ - name : Normalize tag format
38+ id : normalize
39+ run : |
40+ TAG="${{ github.event.inputs.tag }}"
41+ # Remove 'v' prefix if present for consistency
42+ NORMALIZED_TAG=${TAG#v}
43+ # Add 'v' prefix for git operations
44+ GIT_TAG="v${NORMALIZED_TAG}"
45+ echo "tag=${GIT_TAG}" >> $GITHUB_OUTPUT
46+ echo "Normalized tag: ${GIT_TAG}"
47+
48+ - uses : actions/checkout@v4
49+ with :
50+ fetch-tags : true
51+
52+ - name : Verify tag exists
53+ run : |
54+ if ! git tag -l | grep -q "^${{ steps.normalize.outputs.tag }}$"; then
55+ echo "❌ Tag ${{ steps.normalize.outputs.tag }} does not exist"
56+ echo "Available tags:"
57+ git tag -l | tail -10
58+ exit 1
59+ fi
60+ echo "✅ Tag ${{ steps.normalize.outputs.tag }} exists"
61+
62+ fix-package :
63+ needs : validate-inputs
64+ if : ${{ github.event.inputs.publish_package == 'true' }}
65+ runs-on : ubuntu-latest
66+
67+ env :
68+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
69+ TWINE_PASSWORD : ${{ secrets.PYPI_TOKEN }}
70+ DRY_RUN : ${{ github.event.inputs.dry_run }}
71+
72+ steps :
73+ - uses : actions/checkout@v4
74+ with :
75+ ref : ${{ needs.validate-inputs.outputs.normalized_tag }}
76+ fetch-tags : true
77+
78+ - uses : asdf-vm/actions/install@v4
79+
80+ - name : Check if package version already exists on PyPI
81+ run : |
82+ TAG="${{ needs.validate-inputs.outputs.normalized_tag }}"
83+ VERSION=${TAG#v}
84+ echo "Checking if transcribe-me version ${VERSION} exists on PyPI..."
85+
86+ if pip index versions transcribe-me | grep -q "${VERSION}"; then
87+ echo "⚠️ Version ${VERSION} already exists on PyPI"
88+ echo "This will likely fail unless you're using --skip-existing or test PyPI"
89+ else
90+ echo "✅ Version ${VERSION} not found on PyPI, safe to publish"
91+ fi
92+
93+ - name : Publish package to PyPI
94+ run : |
95+ if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
96+ echo "🧪 DRY RUN: Would publish package to PyPI"
97+ echo "Command that would run: make publish-package"
98+ else
99+ echo "📦 Publishing package to PyPI..."
100+ make publish-package
101+ fi
102+
103+ fix-container :
104+ needs : validate-inputs
105+ if : ${{ github.event.inputs.publish_container == 'true' }}
106+ runs-on : ubuntu-latest
107+
108+ strategy :
109+ matrix :
110+ arch : [linux/amd64, linux/arm64]
111+
112+ env :
113+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
114+
115+ steps :
116+ - uses : actions/checkout@v4
117+ with :
118+ ref : ${{ needs.validate-inputs.outputs.normalized_tag }}
119+ fetch-depth : 1
120+
121+ - run : git fetch --tags origin
122+
123+ - uses : docker/setup-qemu-action@v3
124+ - uses : docker/setup-buildx-action@v3
125+
126+ - name : Check existing container images
127+ run : |
128+ TAG="${{ needs.validate-inputs.outputs.normalized_tag }}"
129+ VERSION=${TAG#v}
130+ echo "Checking for existing container images..."
131+
132+ # Check if images already exist (this will fail gracefully if they don't)
133+ docker manifest inspect ghcr.io/echohello-dev/transcribe-me:${VERSION} 2>/dev/null && \
134+ echo "⚠️ Image ghcr.io/echohello-dev/transcribe-me:${VERSION} already exists" || \
135+ echo "✅ Image ghcr.io/echohello-dev/transcribe-me:${VERSION} not found, safe to publish"
136+
137+ docker manifest inspect ghcr.io/echohello-dev/transcribe-me:latest 2>/dev/null && \
138+ echo "⚠️ Image ghcr.io/echohello-dev/transcribe-me:latest already exists (will be overwritten)" || \
139+ echo "✅ Image ghcr.io/echohello-dev/transcribe-me:latest not found"
140+
141+ - name : Publish container image
142+ run : |
143+ if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
144+ echo "🧪 DRY RUN: Would publish container image for ${{ matrix.arch }}"
145+ echo "Command that would run: make publish-image"
146+ else
147+ echo "🐳 Publishing container image for ${{ matrix.arch }}..."
148+ make publish-image
149+ fi
150+ env :
151+ DOCKER_DEFAULT_PLATFORM : ${{ matrix.arch }}
152+
153+ summary :
154+ needs : [validate-inputs, fix-package, fix-container]
155+ if : always()
156+ runs-on : ubuntu-latest
157+ steps :
158+ - name : Release fix summary
159+ run : |
160+ echo "## 🔧 Release Fix Summary" >> $GITHUB_STEP_SUMMARY
161+ echo "" >> $GITHUB_STEP_SUMMARY
162+ echo "**Tag:** ${{ needs.validate-inputs.outputs.normalized_tag }}" >> $GITHUB_STEP_SUMMARY
163+ echo "**Dry Run:** ${{ github.event.inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY
164+ echo "" >> $GITHUB_STEP_SUMMARY
165+
166+ if [[ "${{ github.event.inputs.publish_package }}" == "true" ]]; then
167+ if [[ "${{ needs.fix-package.result }}" == "success" ]]; then
168+ echo "✅ **Package:** Successfully published" >> $GITHUB_STEP_SUMMARY
169+ else
170+ echo "❌ **Package:** Failed to publish" >> $GITHUB_STEP_SUMMARY
171+ fi
172+ else
173+ echo "⏭️ **Package:** Skipped" >> $GITHUB_STEP_SUMMARY
174+ fi
175+
176+ if [[ "${{ github.event.inputs.publish_container }}" == "true" ]]; then
177+ if [[ "${{ needs.fix-container.result }}" == "success" ]]; then
178+ echo "✅ **Container:** Successfully published" >> $GITHUB_STEP_SUMMARY
179+ else
180+ echo "❌ **Container:** Failed to publish" >> $GITHUB_STEP_SUMMARY
181+ fi
182+ else
183+ echo "⏭️ **Container:** Skipped" >> $GITHUB_STEP_SUMMARY
184+ fi
185+
186+ echo "" >> $GITHUB_STEP_SUMMARY
187+ echo "View the [release on GitHub](https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-inputs.outputs.normalized_tag }})" >> $GITHUB_STEP_SUMMARY
0 commit comments