Skip to content

Commit c6c6bb6

Browse files
committed
Create capturecontext/tap tap
0 parents  commit c6c6bb6

7 files changed

Lines changed: 350 additions & 0 deletions

File tree

.github/formulae.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"fxcodex": {
3+
"asset": "fxcodex-universal-apple-darwin",
4+
"repository": "CaptureContext/fxcodex"
5+
}
6+
}

.github/workflows/publish.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: brew pr-pull
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
pull_request:
7+
description: Pull request number
8+
required: true
9+
head_sha:
10+
description: Expected pull request head commit SHA (optional)
11+
12+
jobs:
13+
pr-pull:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
actions: read
17+
checks: read
18+
contents: write
19+
issues: read
20+
pull-requests: write
21+
steps:
22+
- name: Set up Homebrew
23+
uses: Homebrew/actions/setup-homebrew@1f8e202ffddf94def7f42f6fa3a482e821489f9c # 2026.07.10.1
24+
with:
25+
token: ${{ secrets.GITHUB_TOKEN }}
26+
27+
- name: Set up git
28+
uses: Homebrew/actions/git-user-config@1f8e202ffddf94def7f42f6fa3a482e821489f9c # 2026.07.10.1
29+
30+
- name: Pull bottles
31+
env:
32+
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
HEAD_SHA: ${{ inputs.head_sha }}
34+
PULL_REQUEST: ${{ inputs.pull_request }}
35+
run: |
36+
if [[ -n "$HEAD_SHA" ]]
37+
then
38+
brew pr-pull --debug --tap="$GITHUB_REPOSITORY" --head-sha="$HEAD_SHA" "$PULL_REQUEST"
39+
else
40+
brew pr-pull --debug --tap="$GITHUB_REPOSITORY" "$PULL_REQUEST"
41+
fi
42+
43+
- name: Push commits
44+
uses: Homebrew/actions/git-try-push@1f8e202ffddf94def7f42f6fa3a482e821489f9c # 2026.07.10.1
45+
with:
46+
branch: main

.github/workflows/tests.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: brew test-bot
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
test-bot:
11+
strategy:
12+
matrix:
13+
os: [ macos-15-intel, macos-26 ]
14+
include:
15+
- os: ubuntu-latest
16+
container:
17+
image: ghcr.io/homebrew/brew:main
18+
options: --privileged
19+
runs-on: ${{ matrix.os }}
20+
container: ${{ matrix.container }}
21+
permissions:
22+
actions: read
23+
checks: read
24+
contents: read
25+
pull-requests: read
26+
steps:
27+
- name: Set up Homebrew
28+
id: set-up-homebrew
29+
uses: Homebrew/actions/setup-homebrew@1f8e202ffddf94def7f42f6fa3a482e821489f9c # 2026.07.10.1
30+
with:
31+
token: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Cache Homebrew Bundler RubyGems
34+
uses: actions/cache@v5
35+
with:
36+
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
37+
key: ${{ matrix.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
38+
restore-keys: ${{ matrix.os }}-rubygems-
39+
40+
- run: brew test-bot --only-cleanup-before
41+
42+
- run: brew test-bot --only-setup
43+
44+
- run: brew test-bot --only-tap-syntax
45+
- run: brew test-bot --only-formulae
46+
if: github.event_name == 'pull_request'
47+
48+
- name: Upload bottles as artifact
49+
if: always() && github.event_name == 'pull_request'
50+
uses: actions/upload-artifact@v7
51+
with:
52+
name: bottles_${{ matrix.os }}
53+
path: '*.bottle.*'
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Update formula
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
formula:
7+
description: Registered formula name
8+
required: true
9+
type: string
10+
version:
11+
description: Stable release version without a v prefix
12+
required: true
13+
type: string
14+
repository_dispatch:
15+
types:
16+
- formula-release
17+
18+
permissions:
19+
contents: write
20+
21+
concurrency:
22+
group: homebrew-tap-formula-updates
23+
cancel-in-progress: false
24+
25+
jobs:
26+
update:
27+
name: Update formula
28+
runs-on: macos-26
29+
steps:
30+
- name: Check out tap
31+
uses: actions/checkout@v6
32+
33+
- name: Set up Homebrew
34+
uses: Homebrew/actions/setup-homebrew@1f8e202ffddf94def7f42f6fa3a482e821489f9c # 2026.07.10.1
35+
with:
36+
token: ${{ secrets.GITHUB_TOKEN }}
37+
38+
- name: Set up git
39+
uses: Homebrew/actions/git-user-config@1f8e202ffddf94def7f42f6fa3a482e821489f9c # 2026.07.10.1
40+
41+
- name: Update and verify formula
42+
id: update
43+
env:
44+
FORMULA: ${{ inputs.formula || github.event.client_payload.formula }}
45+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46+
VERSION: ${{ inputs.version || github.event.client_payload.version }}
47+
run: |
48+
set -euo pipefail
49+
scripts/update-formula.sh "$FORMULA" "$VERSION"
50+
51+
if git diff --quiet -- "Formula/$FORMULA.rb"
52+
then
53+
echo "changed=false" >> "$GITHUB_OUTPUT"
54+
else
55+
echo "changed=true" >> "$GITHUB_OUTPUT"
56+
fi
57+
58+
- name: Commit and push formula
59+
if: steps.update.outputs.changed == 'true'
60+
env:
61+
FORMULA: ${{ inputs.formula || github.event.client_payload.formula }}
62+
VERSION: ${{ inputs.version || github.event.client_payload.version }}
63+
run: |
64+
set -euo pipefail
65+
git add -- "Formula/$FORMULA.rb"
66+
git commit -m "$FORMULA $VERSION"
67+
git push origin HEAD:main
68+
69+
- name: Report current formula
70+
if: steps.update.outputs.changed == 'false'
71+
env:
72+
FORMULA: ${{ inputs.formula || github.event.client_payload.formula }}
73+
VERSION: ${{ inputs.version || github.event.client_payload.version }}
74+
run: echo "$FORMULA is already at $VERSION."

Formula/fxcodex.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Fxcodex < Formula
2+
desc "Manage isolated Codex workspaces on macOS"
3+
homepage "https://github.com/CaptureContext/fxcodex"
4+
url "https://github.com/CaptureContext/fxcodex/releases/download/0.1.0/fxcodex-universal-apple-darwin"
5+
sha256 "2b98593811abbb438e0efabddadd4341058cf97c431368c7ec2d129da6ab0eba"
6+
license "MIT"
7+
8+
depends_on :macos
9+
10+
on_macos do
11+
depends_on macos: :sonoma
12+
end
13+
14+
def install
15+
bin.install "fxcodex-universal-apple-darwin" => "fxcodex"
16+
end
17+
18+
test do
19+
assert_equal version.to_s, shell_output("#{bin}/fxcodex version").strip
20+
end
21+
end

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# capturecontext tap
2+
3+
Homebrew tap for CaptureContext tools
4+
5+
## [fxcodex](https://github.com/capturecontext/fxcodex)
6+
7+
A macOS CLI for managing isolated Codex workspaces.
8+
9+
### Requirements
10+
11+
- macOS 14 or later
12+
13+
### ⌘ Install
14+
15+
```bash
16+
brew install capturecontext/tap/fxcodex
17+
```
18+
19+
### ⌘ Update
20+
21+
```bash
22+
brew upgrade fxcodex
23+
```
24+

scripts/update-formula.sh

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
if [[ $# -ne 2 ]]
6+
then
7+
echo "Usage: scripts/update-formula.sh <formula> <x.y.z>" >&2
8+
exit 64
9+
fi
10+
11+
readonly formula="$1"
12+
readonly version="$2"
13+
script_directory="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14+
readonly script_directory
15+
tap_directory="$(cd "${script_directory}/.." && pwd)"
16+
readonly tap_directory
17+
readonly registry="${tap_directory}/.github/formulae.json"
18+
19+
if [[ ! "${formula}" =~ ^[a-z0-9][a-z0-9._+-]*$ ]]
20+
then
21+
echo "Invalid formula name '${formula}'." >&2
22+
exit 64
23+
fi
24+
if [[ ! "${version}" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]
25+
then
26+
echo "Version must be plain semantic version such as 0.1.0." >&2
27+
exit 64
28+
fi
29+
30+
for command in brew curl gh jq shasum
31+
do
32+
if ! command -v "${command}" >/dev/null
33+
then
34+
echo "Required command '${command}' was not found." >&2
35+
exit 1
36+
fi
37+
done
38+
39+
if ! repository="$(jq -er --arg formula "${formula}" '.[$formula].repository // empty' "${registry}")"
40+
then
41+
echo "Formula '${formula}' is not registered in ${registry}." >&2
42+
exit 64
43+
fi
44+
readonly repository
45+
if ! asset="$(jq -er --arg formula "${formula}" '.[$formula].asset // empty' "${registry}")"
46+
then
47+
echo "Formula '${formula}' does not define a release asset in ${registry}." >&2
48+
exit 1
49+
fi
50+
readonly asset
51+
readonly formula_path="${tap_directory}/Formula/${formula}.rb"
52+
readonly formula_reference="capturecontext/tap/${formula}"
53+
54+
if [[ ! "${repository}" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]
55+
then
56+
echo "Registry repository '${repository}' is invalid." >&2
57+
exit 1
58+
fi
59+
if [[ ! "${asset}" =~ ^[A-Za-z0-9._-]+$ ]]
60+
then
61+
echo "Registry asset '${asset}' is invalid." >&2
62+
exit 1
63+
fi
64+
if [[ ! -f "${formula_path}" ]]
65+
then
66+
echo "Formula '${formula_path}' does not exist." >&2
67+
exit 1
68+
fi
69+
70+
release_json="$(gh api "repos/${repository}/releases/tags/${version}")"
71+
readonly release_json
72+
if ! jq -e \
73+
--arg version "${version}" \
74+
'.tag_name == $version and .draft == false and .prerelease == false' \
75+
<<<"${release_json}" >/dev/null
76+
then
77+
echo "Release ${repository}@${version} is missing, draft, or prerelease." >&2
78+
exit 1
79+
fi
80+
81+
artifact_url="$(jq -er \
82+
--arg name "${asset}" \
83+
'[.assets[] | select(.name == $name)][0].browser_download_url // empty' \
84+
<<<"${release_json}")"
85+
readonly artifact_url
86+
checksum_url="$(jq -er \
87+
--arg name "${asset}.sha256" \
88+
'[.assets[] | select(.name == $name)][0].browser_download_url // empty' \
89+
<<<"${release_json}")"
90+
readonly checksum_url
91+
92+
temporary_directory="$(mktemp -d)"
93+
readonly temporary_directory
94+
trap 'rm -rf "$temporary_directory"' EXIT
95+
96+
curl --fail --location --retry 3 --silent --show-error \
97+
--output "${temporary_directory}/${asset}" \
98+
"${artifact_url}"
99+
curl --fail --location --retry 3 --silent --show-error \
100+
--output "${temporary_directory}/${asset}.sha256" \
101+
"${checksum_url}"
102+
(
103+
cd "${temporary_directory}"
104+
shasum -a 256 --check "${asset}.sha256"
105+
)
106+
107+
sha256="$(shasum -a 256 "${temporary_directory}/${asset}" | awk '{print $1}')"
108+
readonly sha256
109+
110+
if grep -Fq "url \"${artifact_url}\"" "${formula_path}" &&
111+
grep -Fq "sha256 \"${sha256}\"" "${formula_path}"
112+
then
113+
echo "${formula} is already at ${version}."
114+
else
115+
brew bump-formula-pr \
116+
--write-only \
117+
--no-audit \
118+
--url="${artifact_url}" \
119+
--sha256="${sha256}" \
120+
"${formula_reference}"
121+
fi
122+
123+
brew style "${formula_reference}"
124+
brew audit --formula "${formula_reference}"
125+
HOMEBREW_NO_AUTO_UPDATE=1 brew install "${formula_reference}"
126+
brew test "${formula_reference}"

0 commit comments

Comments
 (0)