Skip to content

Commit ff74417

Browse files
fix(release): replace softprops/action-gh-release with gh CLI to fix missing releases
softprops/action-gh-release v2.5.0 (SHA a06a81a0) introduced a "draft until all artifacts are uploaded" feature (PR #692) that has known bugs causing releases to silently fail finalization. The action creates a draft release, uploads artifacts, then attempts to un-draft it, but the finalization can fail without surfacing errors (see softprops/action-gh-release#709, #704, #713). This left 46 tags (v0.1.45-v0.1.64) with zero published GitHub releases. The fix replaces the action with a direct `gh release create` CLI call, which creates the release atomically with all assets attached in a single operation. This avoids the draft-then-finalize pattern entirely. A post-creation verification step confirms the release is publicly accessible. Also adds a fallback in install.sh: when no GitHub releases exist, the installer now queries the tags API to find the latest version tag before falling back to build-from-source. Fixes #77, fixes #78. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ead0add commit ff74417

2 files changed

Lines changed: 72 additions & 34 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ jobs:
148148
fi
149149
VERSION="${RAW_TAG#v}"
150150
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
151+
echo "tag=${RAW_TAG}" >> "$GITHUB_OUTPUT"
151152
152153
- name: Validate tag matches Cargo.toml version
153154
shell: bash
@@ -208,38 +209,69 @@ jobs:
208209
done
209210
210211
- name: Create GitHub Release
211-
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2
212-
with:
213-
name: v${{ steps.version.outputs.version }}
214-
files: artifacts/*
215-
generate_release_notes: true
216-
body: |
217-
## Installation
218-
219-
### Quick Install (recommended)
220-
```bash
221-
# Linux/macOS
222-
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/coding_agent_session_search/main/install.sh" | bash -s -- --easy-mode --verify
223-
224-
# Windows (PowerShell)
225-
irm https://raw.githubusercontent.com/Dicklesworthstone/coding_agent_session_search/main/install.ps1 | iex
226-
```
227-
228-
### Package Managers
229-
```bash
230-
# Homebrew
231-
brew install dicklesworthstone/tap/cass
232-
233-
# Scoop
234-
scoop bucket add dicklesworthstone https://github.com/Dicklesworthstone/scoop-bucket
235-
scoop install dicklesworthstone/cass
236-
```
237-
238-
### Verify Downloads
239-
All binaries include SHA256 checksums. Download `SHA256SUMS.txt` and verify:
240-
```bash
241-
sha256sum -c SHA256SUMS.txt
242-
```
212+
env:
213+
GH_TOKEN: ${{ github.token }}
214+
TAG: ${{ steps.version.outputs.tag }}
215+
VERSION: ${{ steps.version.outputs.version }}
216+
shell: bash
217+
run: |
218+
echo "Creating release for tag: ${TAG}"
219+
220+
# Delete any leftover draft/broken release for this tag (from prior failed runs)
221+
EXISTING_ID=$(gh api "repos/${{ github.repository }}/releases" \
222+
--paginate --jq ".[] | select(.tag_name == \"${TAG}\") | .id" 2>/dev/null || true)
223+
if [[ -n "$EXISTING_ID" ]]; then
224+
echo "Deleting existing release id=${EXISTING_ID} for tag ${TAG}"
225+
gh api -X DELETE "repos/${{ github.repository }}/releases/${EXISTING_ID}" || true
226+
fi
227+
228+
# Build release body
229+
cat > "$RUNNER_TEMP/release-body.md" <<'EOF'
230+
## Installation
231+
232+
### Quick Install (recommended)
233+
```bash
234+
# Linux/macOS
235+
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/coding_agent_session_search/main/install.sh" | bash -s -- --easy-mode --verify
236+
237+
# Windows (PowerShell)
238+
irm https://raw.githubusercontent.com/Dicklesworthstone/coding_agent_session_search/main/install.ps1 | iex
239+
```
240+
241+
### Package Managers
242+
```bash
243+
# Homebrew
244+
brew install dicklesworthstone/tap/cass
245+
246+
# Scoop
247+
scoop bucket add dicklesworthstone https://github.com/Dicklesworthstone/scoop-bucket
248+
scoop install dicklesworthstone/cass
249+
```
250+
251+
### Verify Downloads
252+
All binaries include SHA256 checksums. Download `SHA256SUMS.txt` and verify:
253+
```bash
254+
sha256sum -c SHA256SUMS.txt
255+
```
256+
EOF
257+
sed -i 's/^ //' "$RUNNER_TEMP/release-body.md"
258+
259+
# Create the release with all artifacts attached atomically
260+
# Using gh CLI directly avoids softprops/action-gh-release v2.5.0 draft
261+
# finalization bugs (see: https://github.com/softprops/action-gh-release/issues/709)
262+
gh release create "${TAG}" artifacts/* \
263+
--repo "${{ github.repository }}" \
264+
--title "v${VERSION}" \
265+
--notes-file "$RUNNER_TEMP/release-body.md" \
266+
--generate-notes \
267+
--latest \
268+
--verify-tag
269+
270+
echo "Release created successfully for ${TAG}."
271+
272+
# Verify the release is publicly accessible
273+
gh release view "${TAG}" --repo "${{ github.repository }}" --json tagName,isDraft,assets \
274+
--jq '{tag: .tagName, draft: .isDraft, asset_count: (.assets | length)}'
243275
244276
outputs:
245277
version: ${{ steps.version.outputs.version }}

‎install.sh‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,21 @@ err() { log "\033[0;31m✗\033[0m $*"; }
2828

2929
resolve_version() {
3030
if [ -n "$VERSION" ]; then return 0; fi
31-
# Fetch latest release tag from GitHub API
3231
local latest=""
3332
if command -v curl >/dev/null 2>&1; then
33+
# Try 1: Fetch latest release tag from GitHub API
3434
latest=$(curl -fsSL "https://api.github.com/repos/$OWNER/$REPO/releases/latest" 2>/dev/null \
3535
| grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/')
36+
# Try 2: If no releases exist, fall back to latest git tag (sorted by version)
37+
if [ -z "$latest" ]; then
38+
warn "No GitHub releases found; falling back to latest git tag"
39+
latest=$(curl -fsSL "https://api.github.com/repos/$OWNER/$REPO/tags?per_page=1" 2>/dev/null \
40+
| grep '"name"' | head -1 | sed 's/.*"name": *"\([^"]*\)".*/\1/')
41+
fi
3642
fi
3743
if [ -n "$latest" ]; then
3844
VERSION="$latest"
39-
info "Using latest release: $VERSION"
45+
info "Using latest version: $VERSION"
4046
elif [ -n "$FALLBACK_VERSION" ]; then
4147
VERSION="$FALLBACK_VERSION"
4248
info "Using fallback version: $VERSION"

0 commit comments

Comments
 (0)