Skip to content

release script#145

Closed
Kitenite wants to merge 2 commits intomainfrom
lavender-sunset-84
Closed

release script#145
Kitenite wants to merge 2 commits intomainfrom
lavender-sunset-84

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Nov 26, 2025

Summary by CodeRabbit

  • Chores
    • Improved internal release workflow automation for desktop app deployments.

✏️ Tip: You can customize this high-level summary in your review settings.

…e-release script

- Add GitHub CLI validation and authentication checks
- Monitor GitHub Actions workflow in real-time
- Display draft release URL when ready
- Add retry logic for workflow and release detection
- Improve error handling and user feedback
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 26, 2025

Walkthrough

A new shell script automates the desktop application release workflow. It validates prerequisites, updates version numbers, commits changes, builds the application, manages Git operations, monitors GitHub Actions workflows, polls for draft releases, and provides user guidance with expected artifacts and next steps.

Changes

Cohort / File(s) Change Summary
Desktop Release Automation
apps/desktop/create-release.sh
New shell script implementing end-to-end release workflow with environment validation, version management, Git operations, build verification, GitHub Actions workflow monitoring, draft release polling, and formatted logging throughout

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Script as create-release.sh
    participant Local as Local Environment
    participant Git as Git/GitHub
    participant Build as Build System
    participant Actions as GitHub Actions
    participant Release as Draft Release

    User->>Script: invoke with version
    Script->>Local: validate prerequisites (gh, bun, pwd)
    Local-->>Script: ✓ or abort
    
    Script->>Local: read current version
    Script->>Build: update version (bun)
    Script->>Git: commit version change
    
    Script->>Local: verify clean working directory
    Script->>Git: check tag doesn't exist
    Git-->>Script: ✓ or abort
    
    Script->>Build: run bun run package
    Build-->>Script: ✓ or abort
    
    Script->>Git: push branch
    Script->>Git: create & push tag
    
    Script->>Actions: locate workflow run
    Actions-->>Script: run detected
    Script->>Actions: watch run progress
    Actions-->>Script: completion status
    
    Note over Script,Release: Poll for draft release
    Script->>Release: query draft release
    Release-->>Script: release URL
    
    Script->>User: print next steps & artifacts
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Multi-step workflow coordination: Script orchestrates complex interactions across Git, GitHub CLI, build system (bun), and GitHub Actions; requires careful review of control flow and error handling at each stage
  • External tool integration: Proper handling of gh, bun, and git CLI invocations; validation of output parsing and command success/failure logic
  • Polling and retry logic: Draft release polling mechanism needs verification for robustness and timeout handling
  • Error handling coverage: Comprehensive error paths must be validated to ensure graceful abort on prerequisites, build failures, or workflow issues

Poem

🐰 A script to hop through the release with grace,
Building and tagging at a rapid pace,
GitHub Actions workflows watched with care,
Draft releases polled from thin digital air,
Bundles and DMGs prepared with flair! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description lacks the required template structure; it contains only bullet points without organized sections for Description, Related Issues, Type of Change, Testing, etc. Restructure the description to follow the template with clear sections: Description, Related Issues, Type of Change, Testing, and any additional notes.
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'release script' is vague and overly generic. While it references the actual change (a release automation script), it lacks specificity about what the script does or why it was created, making it indistinguishable from other potential release-related changes. Consider a more descriptive title that captures the primary purpose, such as 'Add desktop app release automation script' or 'Introduce release workflow with GitHub Actions monitoring.'
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch lavender-sunset-84

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b8473d and ad7d830.

📒 Files selected for processing (1)
  • apps/desktop/create-release.sh (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (1)
apps/desktop/create-release.sh (1)

175-186: Script continues after workflow failure instead of erroring.

Line 175 uses gh run watch ... || warn, which catches any error (including workflow failure) and only issues a warning. The script then continues to poll for a draft release (lines 192–221) even if the workflow failed, which could create a confusing user experience if the release assets were never built.

Verify the intended behavior: should the script exit on workflow failure, or is graceful continuation the desired behavior? If workflow failure should be fatal:

- gh run watch "${WORKFLOW_RUN}" || warn "Workflow monitoring interrupted"
+ if ! gh run watch "${WORKFLOW_RUN}"; then
+     warn "Workflow monitoring interrupted"
+     # Optionally exit here if workflow failure is critical
+ fi

Consider checking the WORKFLOW_STATUS (line 178) before proceeding to draft release polling, or add an explicit guard to prevent unnecessary polling after known failures.


# 3. Update version in package.json
info "Updating version in package.json..."
CURRENT_VERSION=$(node -p "require('./package.json').version")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add Node.js prerequisite check.

Line 96 uses node -p "require('./package.json').version" without verifying Node.js is installed. If Node.js is missing, the script will fail with a confusing error message instead of a clear prerequisite check.

Add a Node.js check after the gh CLI validation (around line 67):

  # Check if authenticated with gh
  if ! gh auth status &> /dev/null; then
      error "Not authenticated with GitHub CLI.\nRun: gh auth login"
  fi
+ 
+ # Check if Node.js is installed
+ if ! command -v node &> /dev/null; then
+     error "Node.js is required but not installed.\nInstall it from: https://nodejs.org/"
+ fi

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/desktop/create-release.sh around line 96 (add check after the gh CLI
validation near line 67), the script uses node to read package.json without
verifying Node.js is installed; add a prerequisite check that verifies the node
executable is available (e.g., using command -v node or which node) and that it
runs (node --version or node -e 'process.exit(0)') and if not present print a
clear error like "Node.js is required to run this script. Please install
Node.js: https://nodejs.org/" and exit with a non-zero status. Ensure the check
happens before any use of node (before the CURRENT_VERSION line) so the script
fails fast with a user-friendly message.

warn "package.json already has version ${VERSION}"
else
# Use bun to update the version
bun version "${VERSION}" --no-git-tag-version
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

bun version command API documentation update package.json


<web_search_result>
Short answer: Bun exposes Bun.version (JS API) and bun --version / bun --revision (CLI) but — as of the sources I checked — there is no official, documented npm-style bun version command that bumps package.json (i.e., a built-in semver bump like npm version). See Bun.version and bun --version docs and the GitHub issue requesting a version subcommand. [1][2][3]

What to use instead

  • Use npm / pnpm / bunx npm version (npm version patch|minor|major) to bump package.json in CI or locally. This works in Bun projects because package.json is standard.
  • Use a dedicated tool (standard-version, semantic-release) or a small script that updates package.json (jq / node script) and optionally creates git tags.
  • If you saw examples using bun version in CI, they were custom workflows or third‑party tooling — check the workflow source before relying on it. [4]

Sources

  1. Bun JS API: Bun.version / Bun.revision. [Bun docs]. [turn1search1]
  2. bun --version / bun --revision and upgrade notes. [Bun installation docs]. [turn1search0]
  3. GitHub issue requesting an npm-style bun version (discussion / status). [turn4view0]
  4. Example GitHub Actions workflow that runs a bun version step in a repo (likely a custom/use-case usage). [turn0search2]

If you want, I can:

  • show a 1-line node/jq script to bump package.json version, or
  • give a CI example using npm version or standard-version that works in Bun projects. Which do you prefer?
    </web_search_result>

Script executed:

cat -n apps/desktop/create-release.sh | sed -n '90,110p'

Repository: superset-sh/superset


<shell_result>
Repository: superset-sh/superset
Exit code: 0

stdout:

    90	    error "Tag ${TAG_NAME} already exists. Use a different version or delete the existing tag."
    91	fi
    92	success "Tag ${TAG_NAME} is available"
    93	
    94	# 3. Update version in package.json
    95	info "Updating version in package.json..."
    96	CURRENT_VERSION=$(node -p "require('./package.json').version")
    97	if [ "${CURRENT_VERSION}" == "${VERSION}" ]; then
    98	    warn "package.json already has version ${VERSION}"
    99	else
   100	    # Use bun to update the version
   101	    bun version "${VERSION}" --no-git-tag-version
   102	    success "Updated package.json from ${CURRENT_VERSION} to ${VERSION}"
   103	
   104	    # Commit the version change
   105	    git add package.json
   106	    git commit -m "chore(desktop): bump version to ${VERSION}"
   107	    success "Committed version change"
   108	fi
   109	
   110	# 4. Verify build works locally

</shell_result>


The bun version command does not exist in Bun's API and will cause the script to fail.

Web search confirms Bun has no official, documented subcommand for bumping package.json versions (unlike npm version or pnpm version). Line 101 attempts to use a non-existent command with an npm-style flag (--no-git-tag-version), which will cause the release script to fail at runtime.

Recommended fix: Replace with one of these approaches:

  • npm version "${VERSION}" --no-git-tag-version (npm works in Bun projects)
  • Use a jq/node script to update package.json directly: node -e "const p = require('./package.json'); p.version = '${VERSION}'; console.log(JSON.stringify(p, null, 2));" > package.json
  • Use bunx npm version to invoke npm through Bun
🤖 Prompt for AI Agents
In apps/desktop/create-release.sh around line 101, the script calls the
non-existent `bun version "${VERSION}" --no-git-tag-version`, which will fail;
replace that invocation with a supported approach such as using `npm version
"${VERSION}" --no-git-tag-version`, running `bunx npm version ...`, or updating
package.json directly via a small node/jq snippet that sets the version and
writes package.json; pick one consistent method for the repo and update the
script to use it (ensuring the VERSION variable is interpolated and the command
does not create a git tag).

Comment on lines +120 to +121
CURRENT_BRANCH=$(git branch --show-current)
git push origin "${CURRENT_BRANCH}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle detached HEAD state when retrieving current branch.

Line 120 uses git branch --show-current to get the current branch. In a detached HEAD state (e.g., when checked out to a specific commit or tag), this command returns an empty string. The subsequent push on line 121 would then fail with a confusing error.

Add a check to handle detached HEAD:

  # 5. Push changes
  info "Pushing changes to remote..."
  CURRENT_BRANCH=$(git branch --show-current)
+ if [ -z "$CURRENT_BRANCH" ]; then
+     error "Unable to determine current branch (detached HEAD state). Please check out a branch before releasing."
+ fi
  git push origin "${CURRENT_BRANCH}"
  success "Changes pushed to ${CURRENT_BRANCH}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CURRENT_BRANCH=$(git branch --show-current)
git push origin "${CURRENT_BRANCH}"
CURRENT_BRANCH=$(git branch --show-current)
if [ -z "$CURRENT_BRANCH" ]; then
error "Unable to determine current branch (detached HEAD state). Please check out a branch before releasing."
fi
git push origin "${CURRENT_BRANCH}"

echo ""

# Get repository information
REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Git remote URL extraction may fail silently if .git suffix is missing.

Line 140 extracts the repository path using sed 's/.*github.com[:/]\(.*\)\.git/\1/'. This regex requires the remote URL to end with .git. If the URL is missing this suffix (uncommon but possible), the pattern won't match, REPO will be empty, and all subsequent URLs (lines 164, 171, 211, 213, 218) will be broken. The script will not error—it will silently produce malformed URLs.

Add validation and a fallback:

  # Get repository information
  REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')
+ if [ -z "$REPO" ]; then
+     # Retry without requiring .git suffix
+     REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)$/\1/')
+ fi
+ if [ -z "$REPO" ]; then
+     warn "Could not parse GitHub repository from remote URL"
+ fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')
REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')
if [ -z "$REPO" ]; then
# Retry without requiring .git suffix
REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)$/\1/')
fi
if [ -z "$REPO" ]; then
warn "Could not parse GitHub repository from remote URL"
fi
🤖 Prompt for AI Agents
In apps/desktop/create-release.sh around line 140, REPO is extracted with a sed
that requires a trailing .git which can produce an empty REPO silently; change
extraction to try a safer fallback and validate the result: first attempt the
existing regex, if that yields empty try a second extraction that does not
require the .git suffix (or strip a trailing .git if present), then if REPO is
still empty print a descriptive error to stderr and exit non‑zero so the script
fails fast; update any subsequent references to rely on the validated REPO
variable.

Comment on lines +153 to +158
WORKFLOW_RUN=$(gh run list --workflow=release-desktop.yml --json databaseId,headBranch,status --jq ".[] | select(.headBranch == \"${TAG_NAME}\") | .databaseId" | head -1)
RETRY_COUNT=$((RETRY_COUNT + 1))

if [ -z "$WORKFLOW_RUN" ] && [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
echo " Still waiting... (attempt $RETRY_COUNT/$MAX_RETRIES)"
fi
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Script executed:

#!/bin/bash
# Read the relevant sections of create-release.sh to understand TAG_NAME and workflow monitoring
echo "=== Reading full create-release.sh ==="
cat -n apps/desktop/create-release.sh

Repository: superset-sh/superset


<shell_result>
Repository: superset-sh/superset
Exit code: 0

stdout:

=== Reading full create-release.sh ===
     1	#!/usr/bin/env bash
     2	
     3	# Desktop App Release Script
     4	# Based on apps/desktop/RELEASE.md
     5	#
     6	# Usage:
     7	#   ./create-release.sh <version>
     8	#   Example: ./create-release.sh 0.0.1
     9	#
    10	# This script will:
    11	# 1. Verify prerequisites (clean git, GitHub CLI authenticated)
    12	# 2. Update package.json version
    13	# 3. Verify build works locally
    14	# 4. Create and push a git tag to trigger the release workflow
    15	# 5. Monitor the GitHub Actions workflow in real-time
    16	# 6. Display the draft release URL when ready
    17	#
    18	# Requirements:
    19	# - GitHub CLI (gh) installed and authenticated
    20	# - Clean working directory
    21	# - Running from monorepo root
    22	
    23	set -e  # Exit on error
    24	
    25	# Colors for output
    26	RED='\033[0;31m'
    27	GREEN='\033[0;32m'
    28	YELLOW='\033[1;33m'
    29	BLUE='\033[0;34m'
    30	NC='\033[0m' # No Color
    31	
    32	# Helper functions
    33	info() {
    34	    echo -e "${BLUE}ℹ ${NC}$1"
    35	}
    36	
    37	success() {
    38	    echo -e "${GREEN}✓${NC} $1"
    39	}
    40	
    41	warn() {
    42	    echo -e "${YELLOW}⚠${NC} $1"
    43	}
    44	
    45	error() {
    46	    echo -e "${RED}✗${NC} $1"
    47	    exit 1
    48	}
    49	
    50	# Check if version argument is provided
    51	if [ -z "$1" ]; then
    52	    error "Usage: $0 <version>\nExample: $0 0.0.1"
    53	fi
    54	
    55	VERSION="$1"
    56	TAG_NAME="desktop-v${VERSION}"
    57	DESKTOP_DIR="apps/desktop"
    58	
    59	# Check if gh CLI is installed
    60	if ! command -v gh &> /dev/null; then
    61	    error "GitHub CLI (gh) is required but not installed.\nInstall it from: https://cli.github.com/"
    62	fi
    63	
    64	# Check if authenticated with gh
    65	if ! gh auth status &> /dev/null; then
    66	    error "Not authenticated with GitHub CLI.\nRun: gh auth login"
    67	fi
    68	
    69	info "Starting release process for version ${VERSION}"
    70	echo ""
    71	
    72	# Check if we're in the monorepo root
    73	if [ ! -f "package.json" ] || [ ! -d "apps/desktop" ]; then
    74	    error "Please run this script from the monorepo root directory"
    75	fi
    76	
    77	# Navigate to desktop app directory
    78	cd "${DESKTOP_DIR}"
    79	
    80	# 1. Check for uncommitted changes
    81	info "Checking for uncommitted changes..."
    82	if ! git diff-index --quiet HEAD --; then
    83	    error "You have uncommitted changes. Please commit or stash them first."
    84	fi
    85	success "Working directory is clean"
    86	
    87	# 2. Check if tag already exists
    88	info "Checking if tag ${TAG_NAME} already exists..."
    89	if git rev-parse "${TAG_NAME}" >/dev/null 2>&1; then
    90	    error "Tag ${TAG_NAME} already exists. Use a different version or delete the existing tag."
    91	fi
    92	success "Tag ${TAG_NAME} is available"
    93	
    94	# 3. Update version in package.json
    95	info "Updating version in package.json..."
    96	CURRENT_VERSION=$(node -p "require('./package.json').version")
    97	if [ "${CURRENT_VERSION}" == "${VERSION}" ]; then
    98	    warn "package.json already has version ${VERSION}"
    99	else
   100	    # Use bun to update the version
   101	    bun version "${VERSION}" --no-git-tag-version
   102	    success "Updated package.json from ${CURRENT_VERSION} to ${VERSION}"
   103	
   104	    # Commit the version change
   105	    git add package.json
   106	    git commit -m "chore(desktop): bump version to ${VERSION}"
   107	    success "Committed version change"
   108	fi
   109	
   110	# 4. Verify build works locally
   111	info "Testing build locally (this may take a few minutes)..."
   112	info "Running: bun run package"
   113	if ! bun run package; then
   114	    error "Build failed. Please fix the issues before releasing."
   115	fi
   116	success "Build completed successfully"
   117	
   118	# 5. Push changes
   119	info "Pushing changes to remote..."
   120	CURRENT_BRANCH=$(git branch --show-current)
   121	git push origin "${CURRENT_BRANCH}"
   122	success "Changes pushed to ${CURRENT_BRANCH}"
   123	
   124	# 6. Create and push tag
   125	info "Creating tag ${TAG_NAME}..."
   126	git tag "${TAG_NAME}"
   127	success "Tag ${TAG_NAME} created"
   128	
   129	info "Pushing tag to trigger release workflow..."
   130	git push origin "${TAG_NAME}"
   131	success "Tag pushed to remote"
   132	
   133	echo ""
   134	echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
   135	echo -e "${GREEN}🎉 Release process initiated successfully!${NC}"
   136	echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
   137	echo ""
   138	
   139	# Get repository information
   140	REPO=$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')
   141	
   142	# 7. Monitor the workflow
   143	info "Monitoring GitHub Actions workflow..."
   144	echo "  Waiting for workflow to start (this may take a few seconds)..."
   145	
   146	# Wait and retry to find the workflow run
   147	MAX_RETRIES=6
   148	RETRY_COUNT=0
   149	WORKFLOW_RUN=""
   150	
   151	while [ $RETRY_COUNT -lt $MAX_RETRIES ] && [ -z "$WORKFLOW_RUN" ]; do
   152	    sleep 5
   153	    WORKFLOW_RUN=$(gh run list --workflow=release-desktop.yml --json databaseId,headBranch,status --jq ".[] | select(.headBranch == \"${TAG_NAME}\") | .databaseId" | head -1)
   154	    RETRY_COUNT=$((RETRY_COUNT + 1))
   155	
   156	    if [ -z "$WORKFLOW_RUN" ] && [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
   157	        echo "  Still waiting... (attempt $RETRY_COUNT/$MAX_RETRIES)"
   158	    fi
   159	done
   160	
   161	if [ -z "$WORKFLOW_RUN" ]; then
   162	    warn "Could not find workflow run automatically"
   163	    echo "  Manual monitoring URL:"
   164	    echo "  https://github.com/${REPO}/actions"
   165	    echo ""
   166	    warn "The workflow may still be starting. Check the URL above in a few moments."
   167	else
   168	    success "Found workflow run: ${WORKFLOW_RUN}"
   169	    echo ""
   170	    info "Watching workflow progress..."
   171	    echo "  View in browser: https://github.com/${REPO}/actions/runs/${WORKFLOW_RUN}"
   172	    echo ""
   173	
   174	    # Watch the workflow (this will stream the status)
   175	    gh run watch "${WORKFLOW_RUN}" || warn "Workflow monitoring interrupted"
   176	
   177	    # Check final status
   178	    WORKFLOW_STATUS=$(gh run view "${WORKFLOW_RUN}" --json conclusion --jq .conclusion)
   179	
   180	    if [ "$WORKFLOW_STATUS" == "success" ]; then
   181	        success "Workflow completed successfully!"
   182	    elif [ "$WORKFLOW_STATUS" == "failure" ]; then
   183	        error "Workflow failed. Please check the logs at: https://github.com/${REPO}/actions/runs/${WORKFLOW_RUN}"
   184	    else
   185	        warn "Workflow ended with status: ${WORKFLOW_STATUS}"
   186	    fi
   187	fi
   188	
   189	echo ""
   190	
   191	# 8. Get and display draft release URL
   192	info "Fetching draft release..."
   193	
   194	# Retry logic for draft release (it may take time to be created)
   195	MAX_RELEASE_RETRIES=10
   196	RELEASE_RETRY_COUNT=0
   197	RELEASE_FOUND=""
   198	
   199	while [ $RELEASE_RETRY_COUNT -lt $MAX_RELEASE_RETRIES ] && [ -z "$RELEASE_FOUND" ]; do
   200	    sleep 3
   201	    RELEASE_FOUND=$(gh release list --json tagName,isDraft --jq ".[] | select(.tagName == \"${TAG_NAME}\" and .isDraft == true) | .tagName")
   202	    RELEASE_RETRY_COUNT=$((RELEASE_RETRY_COUNT + 1))
   203	
   204	    if [ -z "$RELEASE_FOUND" ] && [ $RELEASE_RETRY_COUNT -lt $MAX_RELEASE_RETRIES ]; then
   205	        echo "  Waiting for draft release to be created... (attempt $RELEASE_RETRY_COUNT/$MAX_RELEASE_RETRIES)"
   206	    fi
   207	done
   208	
   209	if [ -z "$RELEASE_FOUND" ]; then
   210	    warn "Draft release not found yet. It may still be processing."
   211	    echo "  Check releases at: https://github.com/${REPO}/releases"
   212	else
   213	    RELEASE_URL="https://github.com/${REPO}/releases/tag/${TAG_NAME}"
   214	    success "Draft release created!"
   215	    echo ""
   216	    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
   217	    echo -e "${BLUE}📦 Draft Release URL:${NC}"
   218	    echo -e "${GREEN}${RELEASE_URL}${NC}"
   219	    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
   220	    echo ""
   221	fi
   222	
   223	echo ""
   224	info "Next steps:"
   225	echo "  1. Review the draft release and edit release notes if needed"
   226	echo "  2. Publish the release when ready"
   227	echo ""
   228	info "Release artifacts will include:"
   229	echo "  • Superset-${VERSION}-arm64.dmg (macOS DMG installer)"
   230	echo "  • Superset-${VERSION}-arm64-mac.zip (macOS zipped app bundle)"
   231	echo ""

</shell_result>


Script executed:

#!/bin/bash
# Find the release-desktop.yml workflow file
echo "=== Searching for release-desktop.yml ==="
find . -name "release-desktop.yml" -type f 2>/dev/null
</parameter>
</invoke>
</invoke>

Repository: superset-sh/superset


<shell_result>
Repository: superset-sh/superset
Exit code: 2

stdout:

=== Searching for release-desktop.yml ===
./.github/workflows/release-desktop.yml

stderr:

/bin/bash: -c: line 5: syntax error near unexpected token `newline'
/bin/bash: -c: line 5: `</parameter>'

</shell_result>


Script executed:

#!/bin/bash
# Read the release-desktop.yml workflow file
echo "=== Reading release-desktop.yml ==="
cat ./.github/workflows/release-desktop.yml

Repository: superset-sh/superset


<shell_result>
Repository: superset-sh/superset
Exit code: 0

stdout:

=== Reading release-desktop.yml ===
name: Release Desktop App

on:
  push:
    tags:
      - "desktop-v*.*.*"
  workflow_dispatch:
    inputs:
      version:
        description: "Version to release (e.g., 1.0.0)"
        required: false
        type: string

jobs:
  build:
    name: Build - macOS (${{ matrix.arch }})
    runs-on: macos-latest

    strategy:
      fail-fast: false
      matrix:
        arch: [arm64]
        # To build for Intel Macs too, uncomment:
        # arch: [arm64, x64]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v1
        with:
          bun-version: latest

      - name: Cache dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.bun/install/cache
          key: ${{ runner.os }}-bun-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-bun-

      - name: Install dependencies
        run: bun install --frozen

      # Run prebuild and compile steps before electron-builder
      - name: Clean dev folder
        working-directory: apps/desktop
        run: bun run clean:dev

      - name: Compile app with electron-vite
        working-directory: apps/desktop
        run: bun run compile:app

      # Build the Electron app for macOS
      - name: Build Electron app
        working-directory: apps/desktop
        env:
          # macOS code signing and notarization
          CSC_LINK: ${{ secrets.MAC_CERTIFICATE }}
          CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }}
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
          APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: bun run package

      # Upload artifacts
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: desktop-mac-${{ matrix.arch }}
          path: |
            apps/desktop/release/*.dmg
            apps/desktop/release/*.zip
          retention-days: 30

  # Create GitHub Release after builds complete
  release:
    name: Create GitHub Release
    needs: build
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/desktop-v')

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: release-artifacts

      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          files: release-artifacts/**/*
          draft: true
          generate_release_notes: true
          name: Superset Desktop ${{ github.ref_name }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

</shell_result>


GitHub CLI "gh run list" headBranch field tag push workflow triggered


<web_search_result>
Short answer: When a workflow run was triggered by pushing a tag, gh run list --json headBranch will usually return an empty/null headBranch. That's because the push ref is a tag (refs/tags/...), not a branch, so there is no "head branch" for the run. Use headSha, the event/ref fields, or inspect github.event (e.g., github.event.ref or github.event.base_ref inside the run) to get the tag or discover branches containing the tag. [1][2][3]

Sources:

  • gh run list JSON fields (headBranch listed). [1]
  • GitHub Actions push event: ref is refs/heads/... for branches and refs/tags/... for tags. [2]
  • Community/StackOverflow notes: tag push runs often have no branch and base_ref may be empty. [3]
    </web_search_result>

gh run list json output fields available event createdAt ref


<web_search_result>
The gh run list --json supports the following fields: attempt, conclusion, createdAt, databaseId, displayTitle, event, headBranch, headSha, name, number, startedAt, status, updatedAt, url, workflowDatabaseId, workflowName. Note: there is no plain "ref" field — use headBranch (branch/ref name) or headSha instead. [1][2]

Sources:

  • GitHub CLI manual (gh run list — JSON fields). [1]
  • gh run list manpage. [2]
    </web_search_result>

Excellent! I now have all the information needed. The verification confirms the review comment is correct and critical. Here's my final analysis:

What happens:

  1. Line 56: TAG_NAME="desktop-v${VERSION}" (e.g., "desktop-v0.0.1") - a git tag
  2. Line 130: The tag is pushed, triggering the workflow
  3. Line 153: The filter attempts to match headBranch == "${TAG_NAME}"
  4. Result: Since the workflow is triggered by a tag push (not a branch push), the headBranch field is null/empty in the gh run list output. The filter will never match.

The script will always fall through to the "Could not find workflow run automatically" warning, preventing real-time workflow monitoring.


Workflow detection logic will never match—incorrect filtering criterion on tag-triggered workflow runs.

Line 153 filters on headBranch == "${TAG_NAME}", but when GitHub Actions is triggered by a tag push (not a branch push), the headBranch field is null/empty because the push ref is refs/tags/..., not refs/heads/.... The tag name (e.g., desktop-v0.0.1) cannot match a branch field.

The correct fix is to filter on the branch that was pushed:

  while [ $RETRY_COUNT -lt $MAX_RETRIES ] && [ -z "$WORKFLOW_RUN" ]; do
      sleep 5
-     WORKFLOW_RUN=$(gh run list --workflow=release-desktop.yml --json databaseId,headBranch,status --jq ".[] | select(.headBranch == \"${TAG_NAME}\") | .databaseId" | head -1)
+     WORKFLOW_RUN=$(gh run list --workflow=release-desktop.yml --json databaseId,headBranch,status --jq ".[] | select(.headBranch == \"${CURRENT_BRANCH}\") | .databaseId" | head -1)
      RETRY_COUNT=$((RETRY_COUNT + 1))

The variable CURRENT_BRANCH is already captured at line 120, so this requires no additional setup.

🤖 Prompt for AI Agents
In apps/desktop/create-release.sh around lines 153 to 158, the gh run list
filter incorrectly compares headBranch to the tag name (TAG_NAME) which will
never match for a tag-triggered workflow; replace the filter to use the branch
variable captured earlier (CURRENT_BRANCH) so the jq selection uses .headBranch
== "${CURRENT_BRANCH}" (or otherwise check .headRef/.headSha if you intended to
match a tag) and ensure RETRY logic remains the same.

@Kitenite Kitenite changed the title lavender sunset 84 release script Nov 26, 2025
@Kitenite Kitenite closed this Nov 27, 2025
@Kitenite Kitenite deleted the lavender-sunset-84 branch November 29, 2025 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant