Skip to content

Commit 150c6dd

Browse files
nsheapsclaude
andauthored
Add mise/ubi support with platform-specific release assets (#17)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 38dcafe commit 150c6dd

9 files changed

Lines changed: 111 additions & 68 deletions

File tree

.editorconfig

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ charset = utf-8
99
trim_trailing_whitespace = true
1010
insert_final_newline = true
1111

12-
[*.json]
13-
insert_final_newline = ignore
14-
1512
[Makefile]
1613
indent_style = tab
1714

.github/workflows/check.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ jobs:
1414
- name: Checkout repository
1515
uses: actions/checkout@v4
1616

17+
- name: Setup mise
18+
uses: jdx/mise-action@v2
19+
1720
- name: Find bash scripts
1821
id: find-bash
1922
run: |

.github/workflows/release.yaml

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,29 @@ jobs:
3838

3939
- name: Run release-it
4040
id: release
41+
env:
42+
GITHUB_TOKEN: ${{ steps.auth.outputs.token }}
4143
run: |
4244
yarn release-it --ci
4345
TAG=$(git describe --tags --abbrev=0)
4446
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
4547
echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
4648
49+
- name: Upload release assets
50+
env:
51+
GITHUB_TOKEN: ${{ steps.auth.outputs.token }}
52+
run: |
53+
TAG="${{ steps.release.outputs.tag }}"
54+
# git-wt is a platform-independent bash script, but ubi (used by
55+
# mise) expects assets named with OS/arch patterns. Upload copies
56+
# for each supported platform so `mise install ubi:nsheaps/git-wt`
57+
# works out of the box.
58+
for platform in linux-amd64 linux-arm64 darwin-amd64 darwin-arm64; do
59+
cp bin/git-wt "git-wt-${platform}"
60+
done
61+
gh release upload "$TAG" git-wt-linux-amd64 git-wt-linux-arm64 git-wt-darwin-amd64 git-wt-darwin-arm64
62+
rm -f git-wt-linux-amd64 git-wt-linux-arm64 git-wt-darwin-amd64 git-wt-darwin-arm64
63+
4764
update-homebrew:
4865
needs: release
4966
runs-on: ubuntu-latest
@@ -72,11 +89,10 @@ jobs:
7289
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
7390
7491
# Download archive tarball and calculate SHA256
75-
# Archive is available instantly (no CDN delay like release assets)
7692
TARBALL_URL="https://github.com/${{ github.repository }}/archive/refs/tags/${TAG}.tar.gz"
7793
echo "Downloading tarball from: $TARBALL_URL"
7894
curl -fsSL "$TARBALL_URL" -o /tmp/archive.tar.gz
79-
SHA256=$(shasum -a 256 /tmp/archive.tar.gz | cut -d' ' -f1)
95+
SHA256=$(sha256sum /tmp/archive.tar.gz | cut -d' ' -f1)
8096
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
8197
echo "Successfully got SHA256: $SHA256"
8298
@@ -96,7 +112,17 @@ jobs:
96112
run: |
97113
gomplate -f Formula/git-wt.rb.gotmpl -o homebrew-devsetup/Formula/git-wt.rb
98114
99-
- name: Create PR to update formula with auto-merge
115+
- name: Close stale formula PRs
116+
run: |
117+
cd homebrew-devsetup
118+
# Close any open PRs from previous formula updates — they're superseded
119+
gh pr list --state open --search "chore: update git-wt to" --json number,title --jq '.[].number' | while read -r pr_num; do
120+
echo "Closing superseded PR #${pr_num}"
121+
gh pr close "$pr_num" --comment "Superseded by v${{ steps.release.outputs.version }} update."
122+
done
123+
124+
- name: Create PR to update formula
125+
id: formula-pr
100126
env:
101127
RELEASE_URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.release.outputs.tag }}
102128
JOB_URL: ${{ env.GITHUB_JOB_URL }}
@@ -105,22 +131,37 @@ jobs:
105131
run: |
106132
cd homebrew-devsetup
107133
BRANCH="bump-git-wt-${VERSION}"
134+
135+
# Delete remote branch if it exists from a previous failed run
136+
git push origin --delete "$BRANCH" 2>/dev/null || true
137+
108138
git checkout -b "$BRANCH"
109139
git add Formula/git-wt.rb
110140
git commit -m "chore: update git-wt to ${VERSION}"
111141
git push -u origin "$BRANCH"
112142
113-
# Create PR body file
114-
cat > /tmp/pr-body.md << 'BODY_EOF'
115-
Automated formula update from git-wt release
116-
BODY_EOF
117-
echo "" >> /tmp/pr-body.md
118-
echo "**Release:** ${RELEASE_URL}" >> /tmp/pr-body.md
119-
echo "**Workflow:** ${JOB_URL}" >> /tmp/pr-body.md
143+
printf 'Automated formula update from git-wt release\n\n**Release:** %s\n**Workflow:** %s\n' "$RELEASE_URL" "$JOB_URL" > /tmp/pr-body.md
120144
121145
PR_URL=$(gh pr create \
122146
--title "chore: update git-wt to ${VERSION}" \
123147
--body-file /tmp/pr-body.md \
124148
--base main)
125-
# Enable auto-merge with squash
126-
gh pr merge "$PR_URL" --auto --squash
149+
echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT"
150+
151+
- name: Enable auto-merge with retry
152+
env:
153+
PR_URL: ${{ steps.formula-pr.outputs.pr_url }}
154+
run: |
155+
# Retry auto-merge — CI checks on the target repo need time to start,
156+
# and the GraphQL API rejects enablePullRequestAutoMerge while the PR
157+
# is in "unstable" (checks pending) status.
158+
for attempt in 1 2 3 4 5; do
159+
if gh pr merge "$PR_URL" --auto --squash; then
160+
echo "Auto-merge enabled successfully on attempt ${attempt}"
161+
exit 0
162+
fi
163+
wait=$((attempt * 10))
164+
echo "Auto-merge not ready (attempt ${attempt}/5), waiting ${wait}s..."
165+
sleep "$wait"
166+
done
167+
echo "::warning::Could not enable auto-merge after 5 attempts. PR was created successfully at ${PR_URL} — merge manually or re-run."

docs/specs/live/cli-non-interactive-mode.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@ Command-line interface for scripting and non-TTY environments.
1111
### Functional Requirements
1212

1313
1. **TTY Detection**
14-
- Detect when stdin/stdout are not TTY
15-
- Automatically switch to non-interactive behavior
14+
- Detect when stdin/stdout are not TTY
15+
- Automatically switch to non-interactive behavior
1616

1717
2. **Usage Display (no arguments)**
18-
- Print usage information
19-
- List existing worktrees with paths
20-
- List branches without worktrees
18+
- Print usage information
19+
- List existing worktrees with paths
20+
- List branches without worktrees
2121

2222
3. **Branch Switch (`git-wt [branch]`)**
23-
- Create worktree if doesn't exist
24-
- Print worktree path to stdout (for `cd "$(git-wt branch)"`)
25-
- Silent operation (no interactive prompts)
23+
- Create worktree if doesn't exist
24+
- Print worktree path to stdout (for `cd "$(git-wt branch)"`)
25+
- Silent operation (no interactive prompts)
2626

2727
4. **Exec Flags**
28-
- `--exec` - Spawn shell in worktree (override default)
29-
- `--no-exec` - Print path only (default in CLI mode)
28+
- `--exec` - Spawn shell in worktree (override default)
29+
- `--no-exec` - Print path only (default in CLI mode)
3030

3131
5. **Error Handling**
32-
- Exit with non-zero status on errors
33-
- Print errors to stderr
32+
- Exit with non-zero status on errors
33+
- Print errors to stderr
3434

3535
### Non-Functional Requirements
3636

@@ -58,8 +58,8 @@ cd "$(git-wt feature-branch)"
5858

5959
### Usage Output
6060
```
61-
Usage: git-wt [branch] Switch to or create worktree
62-
git-wt d [branch] Delete worktree (requires --force)
61+
Usage: git-wt [branch] Switch to or create worktree
62+
git-wt d [branch] Delete worktree (requires --force)
6363
6464
Options:
6565
--exec Spawn shell in worktree (instead of printing path)

docs/specs/live/interactive-worktree-selector.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,27 @@ The primary interactive TUI for selecting and managing git worktrees using fzf.
1111
### Functional Requirements
1212

1313
1. **Worktree Listing**
14-
- Display all existing worktrees with their branch names and paths
15-
- Show root checkout labeled as `[root]`
16-
- Show worktrees labeled as `[worktree]`
14+
- Display all existing worktrees with their branch names and paths
15+
- Show root checkout labeled as `[root]`
16+
- Show worktrees labeled as `[worktree]`
1717

1818
2. **Branch Listing**
19-
- Display local branches without worktrees
20-
- Display remote branches (with `origin/` prefix stripped in display)
19+
- Display local branches without worktrees
20+
- Display remote branches (with `origin/` prefix stripped in display)
2121

2222
3. **Selection Interface**
23-
- Use fzf for fuzzy-finding selection
24-
- Support keyboard navigation
25-
- Show preview panel with PR information (if gh CLI available)
23+
- Use fzf for fuzzy-finding selection
24+
- Support keyboard navigation
25+
- Show preview panel with PR information (if gh CLI available)
2626

2727
4. **Actions on Selection**
28-
- Switch to existing worktree
29-
- Create new worktree for branch without one
30-
- Create new branch and worktree
28+
- Switch to existing worktree
29+
- Create new worktree for branch without one
30+
- Create new branch and worktree
3131

3232
5. **Post-Selection Behavior**
33-
- Spawn new shell in selected worktree directory
34-
- Support `--no-exec` to print path instead
33+
- Spawn new shell in selected worktree directory
34+
- Support `--no-exec` to print path instead
3535

3636
### Non-Functional Requirements
3737

docs/specs/live/repo-switching.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ Switch between different git repositories when not already in a repo.
1111
### Functional Requirements
1212

1313
1. **Repo Discovery**
14-
- Scan configured directory for git repositories
15-
- Default scan directory: `~/src`
16-
- Configurable via `--scan-dir DIR`
14+
- Scan configured directory for git repositories
15+
- Default scan directory: `~/src`
16+
- Configurable via `--scan-dir DIR`
1717

1818
2. **Repo Selection**
19-
- Use fzf for fuzzy-finding repos
20-
- Display repo paths for selection
19+
- Use fzf for fuzzy-finding repos
20+
- Display repo paths for selection
2121

2222
3. **Post-Selection**
23-
- Continue to normal worktree selector for chosen repo
23+
- Continue to normal worktree selector for chosen repo
2424

2525
### Non-Functional Requirements
2626

docs/specs/live/upgrade-notifications.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@ Background check for new releases with non-intrusive notification.
1111
### Functional Requirements
1212

1313
1. **Background Check**
14-
- Check GitHub releases API asynchronously
15-
- Do not block main script execution
16-
- Cache/throttle to avoid excessive API calls
14+
- Check GitHub releases API asynchronously
15+
- Do not block main script execution
16+
- Cache/throttle to avoid excessive API calls
1717

1818
2. **Version Comparison**
19-
- Compare current version against latest release
20-
- Only notify if newer version available
19+
- Compare current version against latest release
20+
- Only notify if newer version available
2121

2222
3. **Notification Display**
23-
- Show at script exit (after main operation completes)
24-
- Display current version and available version
25-
- Provide upgrade command
23+
- Show at script exit (after main operation completes)
24+
- Display current version and available version
25+
- Provide upgrade command
2626

2727
4. **Suppression**
28-
- Do NOT show in non-interactive mode
29-
- Only show when TTY available
28+
- Do NOT show in non-interactive mode
29+
- Only show when TTY available
3030

3131
### Non-Functional Requirements
3232

docs/specs/live/worktree-deletion.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@ Delete git worktrees with appropriate safety confirmations.
1111
### Functional Requirements
1212

1313
1. **Delete Command**
14-
- `git-wt d [branch]` to delete worktree for specified branch
15-
- Cannot delete root checkout
14+
- `git-wt d [branch]` to delete worktree for specified branch
15+
- Cannot delete root checkout
1616

1717
2. **Interactive Mode**
18-
- Show confirmation prompt via gum
19-
- If uncommitted changes, show force confirmation
20-
- Use gum spinner during deletion
18+
- Show confirmation prompt via gum
19+
- If uncommitted changes, show force confirmation
20+
- Use gum spinner during deletion
2121

2222
3. **Non-Interactive Mode**
23-
- Require `--force` flag
24-
- Fail with helpful error if `--force` not provided
23+
- Require `--force` flag
24+
- Fail with helpful error if `--force` not provided
2525

2626
4. **Error Handling**
27-
- Error if branch has no worktree
28-
- Error if trying to delete root checkout
29-
- Handle uncommitted changes gracefully
27+
- Error if branch has no worktree
28+
- Error if trying to delete root checkout
29+
- Handle uncommitted changes gracefully
3030

3131
### Non-Functional Requirements
3232

mise.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[tools]
22
node = "lts"
33
yarn = "4"
4+
shellcheck = "latest"
5+
shfmt = "latest"
46

57
[tasks.test]
68
description = "Run CLI tests"

0 commit comments

Comments
 (0)