httpcat-cli 0.0.17 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +27 -0
- package/.github/workflows/README.md +49 -0
- package/.github/workflows/ci.yml +101 -0
- package/.github/workflows/homebrew-tap.yml +63 -0
- package/.github/workflows/release.yml +361 -0
- package/README.md +102 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +11 -0
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/positions.d.ts.map +1 -0
- package/dist/commands/positions.js +136 -0
- package/dist/commands/positions.js.map +1 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +114 -12
- package/dist/index.js.map +1 -1
- package/dist/interactive/shell.d.ts.map +1 -1
- package/dist/interactive/shell.js +76 -11
- package/dist/interactive/shell.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +20 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/utils/loading.d.ts.map +1 -0
- package/dist/utils/loading.js +61 -0
- package/dist/utils/loading.js.map +1 -0
- package/homebrew-httpcat/Formula/httpcat.rb +3 -3
- package/homebrew-httpcat/homebrew-httpcat/Formula/httpcat.rb +3 -3
- package/jest.config.js +38 -0
- package/monitor-foobar.js +38 -39
- package/package.json +11 -2
- package/tests/README.md +134 -0
- package/chat-automation.js +0 -171
- package/httpcat-mcp.json +0 -11
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Enable version updates for npm
|
|
4
|
+
- package-ecosystem: "npm"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
open-pull-requests-limit: 5
|
|
9
|
+
labels:
|
|
10
|
+
- "dependencies"
|
|
11
|
+
- "automated"
|
|
12
|
+
commit-message:
|
|
13
|
+
prefix: "chore"
|
|
14
|
+
include: "scope"
|
|
15
|
+
|
|
16
|
+
# Enable version updates for GitHub Actions
|
|
17
|
+
- package-ecosystem: "github-actions"
|
|
18
|
+
directory: "/"
|
|
19
|
+
schedule:
|
|
20
|
+
interval: "weekly"
|
|
21
|
+
labels:
|
|
22
|
+
- "github-actions"
|
|
23
|
+
- "automated"
|
|
24
|
+
commit-message:
|
|
25
|
+
prefix: "ci"
|
|
26
|
+
include: "scope"
|
|
27
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# GitHub Actions Workflows
|
|
2
|
+
|
|
3
|
+
This directory contains automated workflows for CI/CD and releases.
|
|
4
|
+
|
|
5
|
+
## Workflows
|
|
6
|
+
|
|
7
|
+
### `ci.yml`
|
|
8
|
+
Continuous Integration workflow that runs on every push and pull request:
|
|
9
|
+
- Runs tests across multiple Node.js versions (18, 20, 22)
|
|
10
|
+
- Type checking and linting
|
|
11
|
+
- Security audits
|
|
12
|
+
- Code coverage reporting
|
|
13
|
+
|
|
14
|
+
### `release.yml`
|
|
15
|
+
Automated release workflow that:
|
|
16
|
+
- Triggers on version tags (v*.*.*) or manual dispatch
|
|
17
|
+
- Validates version format
|
|
18
|
+
- Runs tests and builds
|
|
19
|
+
- Publishes to npm
|
|
20
|
+
- Updates Homebrew formula
|
|
21
|
+
- Creates GitHub release with auto-generated release notes
|
|
22
|
+
|
|
23
|
+
### `homebrew-tap.yml`
|
|
24
|
+
Manual workflow to update the Homebrew formula in the tap repository.
|
|
25
|
+
|
|
26
|
+
## Secrets Required
|
|
27
|
+
|
|
28
|
+
Configure these in Repository Settings → Secrets and variables → Actions:
|
|
29
|
+
|
|
30
|
+
- `NPM_TOKEN`: npm authentication token with publish permissions
|
|
31
|
+
- Generate at: https://www.npmjs.com/settings/YOUR_USERNAME/tokens
|
|
32
|
+
- Required scopes: `read:packages`, `write:packages`
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### Creating a Release
|
|
37
|
+
|
|
38
|
+
1. **Automatic (recommended)**: Push a version tag
|
|
39
|
+
```bash
|
|
40
|
+
git tag v1.2.3
|
|
41
|
+
git push origin v1.2.3
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. **Manual**: Use GitHub Actions UI
|
|
45
|
+
- Go to Actions → Release → Run workflow
|
|
46
|
+
- Enter version number
|
|
47
|
+
- Click Run workflow
|
|
48
|
+
|
|
49
|
+
See [RELEASE.md](../RELEASE.md) for detailed release instructions.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
NODE_VERSION: '20'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Test
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
node-version: ['18', '20', '22']
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Setup Node.js ${{ matrix.node-version }}
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: ${{ matrix.node-version }}
|
|
27
|
+
cache: 'yarn'
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: yarn install --frozen-lockfile
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: yarn test
|
|
34
|
+
|
|
35
|
+
- name: Build
|
|
36
|
+
run: yarn build
|
|
37
|
+
|
|
38
|
+
- name: Upload coverage reports
|
|
39
|
+
if: matrix.node-version == '20'
|
|
40
|
+
uses: codecov/codecov-action@v4
|
|
41
|
+
with:
|
|
42
|
+
files: ./coverage/lcov.info
|
|
43
|
+
flags: unittests
|
|
44
|
+
name: codecov-umbrella
|
|
45
|
+
fail_ci_if_error: false
|
|
46
|
+
|
|
47
|
+
lint:
|
|
48
|
+
name: Lint & Type Check
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
steps:
|
|
51
|
+
- name: Checkout code
|
|
52
|
+
uses: actions/checkout@v4
|
|
53
|
+
|
|
54
|
+
- name: Setup Node.js
|
|
55
|
+
uses: actions/setup-node@v4
|
|
56
|
+
with:
|
|
57
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
58
|
+
cache: 'yarn'
|
|
59
|
+
|
|
60
|
+
- name: Install dependencies
|
|
61
|
+
run: yarn install --frozen-lockfile
|
|
62
|
+
|
|
63
|
+
- name: Type check
|
|
64
|
+
run: yarn build --noEmit || npx tsc --noEmit
|
|
65
|
+
|
|
66
|
+
- name: Check formatting (if configured)
|
|
67
|
+
continue-on-error: true
|
|
68
|
+
run: |
|
|
69
|
+
if [ -f ".prettierrc" ] || [ -f ".prettierrc.js" ] || [ -f ".prettierrc.json" ]; then
|
|
70
|
+
npx prettier --check "**/*.{ts,js,json,md}" || true
|
|
71
|
+
else
|
|
72
|
+
echo "No formatter configured, skipping..."
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
security:
|
|
76
|
+
name: Security Audit
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
steps:
|
|
79
|
+
- name: Checkout code
|
|
80
|
+
uses: actions/checkout@v4
|
|
81
|
+
|
|
82
|
+
- name: Setup Node.js
|
|
83
|
+
uses: actions/setup-node@v4
|
|
84
|
+
with:
|
|
85
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
86
|
+
cache: 'yarn'
|
|
87
|
+
|
|
88
|
+
- name: Install dependencies
|
|
89
|
+
run: yarn install --frozen-lockfile
|
|
90
|
+
|
|
91
|
+
- name: Run security audit
|
|
92
|
+
run: yarn audit --level moderate || true
|
|
93
|
+
|
|
94
|
+
- name: Check for known vulnerabilities
|
|
95
|
+
uses: snyk/actions/node@master
|
|
96
|
+
continue-on-error: true
|
|
97
|
+
env:
|
|
98
|
+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
99
|
+
with:
|
|
100
|
+
args: --severity-threshold=high
|
|
101
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Homebrew Tap Update
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
version:
|
|
7
|
+
description: 'Version to update (e.g., 1.2.3)'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
update-formula:
|
|
13
|
+
name: Update Homebrew Formula
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout homebrew tap
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
repository: hathbanger/homebrew-httpcat
|
|
20
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
21
|
+
path: homebrew-tap
|
|
22
|
+
|
|
23
|
+
- name: Get npm package SHA256
|
|
24
|
+
id: npm-sha
|
|
25
|
+
run: |
|
|
26
|
+
VERSION="${{ github.event.inputs.version }}"
|
|
27
|
+
TARBALL_URL="https://registry.npmjs.org/httpcat-cli/-/httpcat-cli-${VERSION}.tgz"
|
|
28
|
+
|
|
29
|
+
echo "Downloading tarball to calculate SHA256..."
|
|
30
|
+
curl -L -o package.tgz "$TARBALL_URL"
|
|
31
|
+
SHA256=$(shasum -a 256 package.tgz | cut -d' ' -f1)
|
|
32
|
+
echo "sha256=$SHA256" >> $GITHUB_OUTPUT
|
|
33
|
+
echo "✅ SHA256: $SHA256"
|
|
34
|
+
|
|
35
|
+
- name: Update Homebrew formula
|
|
36
|
+
run: |
|
|
37
|
+
VERSION="${{ github.event.inputs.version }}"
|
|
38
|
+
SHA256="${{ steps.npm-sha.outputs.sha256 }}"
|
|
39
|
+
FORMULA_FILE="homebrew-tap/Formula/httpcat.rb"
|
|
40
|
+
|
|
41
|
+
# Update version
|
|
42
|
+
sed -i.bak "s|url \".*httpcat-cli-.*\.tgz\"|url \"https://registry.npmjs.org/httpcat-cli/-/httpcat-cli-${VERSION}.tgz\"|" "$FORMULA_FILE"
|
|
43
|
+
|
|
44
|
+
# Update SHA256
|
|
45
|
+
sed -i.bak "s|sha256 \".*\"|sha256 \"${SHA256}\"|" "$FORMULA_FILE"
|
|
46
|
+
|
|
47
|
+
# Update test version
|
|
48
|
+
sed -i.bak "s|assert_match \".*\"|assert_match \"${VERSION}\"|" "$FORMULA_FILE"
|
|
49
|
+
|
|
50
|
+
rm -f "${FORMULA_FILE}.bak"
|
|
51
|
+
|
|
52
|
+
echo "✅ Updated Homebrew formula:"
|
|
53
|
+
cat "$FORMULA_FILE"
|
|
54
|
+
|
|
55
|
+
- name: Commit and push
|
|
56
|
+
run: |
|
|
57
|
+
cd homebrew-tap
|
|
58
|
+
git config user.name "github-actions[bot]"
|
|
59
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
60
|
+
git add Formula/httpcat.rb
|
|
61
|
+
git commit -m "Update httpcat to ${{ github.event.inputs.version }}" || exit 0
|
|
62
|
+
git push
|
|
63
|
+
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*' # Triggers on semantic version tags (e.g., v1.2.3)
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: 'Version to release (e.g., 1.2.3)'
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
NODE_VERSION: '20'
|
|
16
|
+
REGISTRY_URL: 'https://registry.npmjs.org'
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# Job 1: Validate and prepare release
|
|
20
|
+
prepare:
|
|
21
|
+
name: Prepare Release
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
outputs:
|
|
24
|
+
version: ${{ steps.version.outputs.version }}
|
|
25
|
+
tag: ${{ steps.version.outputs.tag }}
|
|
26
|
+
npm-version: ${{ steps.version.outputs.npm-version }}
|
|
27
|
+
release-notes: ${{ steps.notes.outputs.notes }}
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout code
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
with:
|
|
32
|
+
fetch-depth: 0 # Full history for changelog generation
|
|
33
|
+
|
|
34
|
+
- name: Setup Node.js
|
|
35
|
+
uses: actions/setup-node@v4
|
|
36
|
+
with:
|
|
37
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
38
|
+
registry-url: ${{ env.REGISTRY_URL }}
|
|
39
|
+
|
|
40
|
+
- name: Extract version from tag
|
|
41
|
+
id: version
|
|
42
|
+
run: |
|
|
43
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
44
|
+
VERSION="${{ github.event.inputs.version }}"
|
|
45
|
+
# Remove 'v' prefix if present
|
|
46
|
+
VERSION=${VERSION#v}
|
|
47
|
+
else
|
|
48
|
+
# Extract from tag (e.g., v1.2.3 -> 1.2.3)
|
|
49
|
+
VERSION=${GITHUB_REF#refs/tags/v}
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Validate semantic version format
|
|
53
|
+
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9-]+(\.[0-9]+)?)?$'; then
|
|
54
|
+
echo "❌ Invalid version format: $VERSION"
|
|
55
|
+
echo "Expected format: X.Y.Z or X.Y.Z-prerelease"
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
60
|
+
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
|
|
61
|
+
echo "npm-version=$VERSION" >> $GITHUB_OUTPUT
|
|
62
|
+
echo "✅ Version: $VERSION"
|
|
63
|
+
|
|
64
|
+
- name: Verify version in package.json
|
|
65
|
+
run: |
|
|
66
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
67
|
+
RELEASE_VERSION="${{ steps.version.outputs.version }}"
|
|
68
|
+
|
|
69
|
+
if [ "$CURRENT_VERSION" != "$RELEASE_VERSION" ]; then
|
|
70
|
+
echo "⚠️ Warning: package.json version ($CURRENT_VERSION) doesn't match release version ($RELEASE_VERSION)"
|
|
71
|
+
echo "Updating package.json..."
|
|
72
|
+
npm version "$RELEASE_VERSION" --no-git-tag-version --allow-same-version
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
- name: Generate release notes
|
|
76
|
+
id: notes
|
|
77
|
+
uses: actions/github-script@v7
|
|
78
|
+
with:
|
|
79
|
+
script: |
|
|
80
|
+
const { data: releases } = await github.rest.repos.listReleases({
|
|
81
|
+
owner: context.repo.owner,
|
|
82
|
+
repo: context.repo.repo,
|
|
83
|
+
per_page: 1
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const lastTag = releases.length > 0 ? releases[0].tag_name : null;
|
|
87
|
+
const currentTag = 'v${{ steps.version.outputs.version }}';
|
|
88
|
+
|
|
89
|
+
// Get commits since last release
|
|
90
|
+
let baseSha;
|
|
91
|
+
if (lastTag) {
|
|
92
|
+
try {
|
|
93
|
+
const { data: tagData } = await github.rest.git.getRef({
|
|
94
|
+
owner: context.repo.owner,
|
|
95
|
+
repo: context.repo.repo,
|
|
96
|
+
ref: `tags/${lastTag}`
|
|
97
|
+
});
|
|
98
|
+
baseSha = tagData.object.sha;
|
|
99
|
+
} catch (e) {
|
|
100
|
+
// If tag ref doesn't exist, try to get commit from tag
|
|
101
|
+
const { data: tagData } = await github.rest.repos.getCommit({
|
|
102
|
+
owner: context.repo.owner,
|
|
103
|
+
repo: context.repo.repo,
|
|
104
|
+
ref: lastTag
|
|
105
|
+
});
|
|
106
|
+
baseSha = tagData.sha;
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
// Get the first commit or main branch
|
|
110
|
+
const { data: branchData } = await github.rest.repos.getBranch({
|
|
111
|
+
owner: context.repo.owner,
|
|
112
|
+
repo: context.repo.repo,
|
|
113
|
+
branch: 'main'
|
|
114
|
+
});
|
|
115
|
+
baseSha = branchData.commit.sha;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const { data: commits } = await github.rest.repos.compareCommits({
|
|
119
|
+
owner: context.repo.owner,
|
|
120
|
+
repo: context.repo.repo,
|
|
121
|
+
base: baseSha,
|
|
122
|
+
head: context.sha
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Categorize commits
|
|
126
|
+
const features = [];
|
|
127
|
+
const fixes = [];
|
|
128
|
+
const docs = [];
|
|
129
|
+
const chore = [];
|
|
130
|
+
const breaking = [];
|
|
131
|
+
|
|
132
|
+
for (const commit of commits.commits) {
|
|
133
|
+
const message = commit.commit.message;
|
|
134
|
+
const firstLine = message.split('\n')[0];
|
|
135
|
+
|
|
136
|
+
if (firstLine.match(/^BREAKING/)) {
|
|
137
|
+
breaking.push(`- ${firstLine.replace(/^BREAKING[:\s]+/i, '')}`);
|
|
138
|
+
} else if (firstLine.match(/^feat(ure)?[(:]/i)) {
|
|
139
|
+
features.push(`- ${firstLine.replace(/^feat(ure)?[(:]\s*/i, '')}`);
|
|
140
|
+
} else if (firstLine.match(/^fix[(]/i)) {
|
|
141
|
+
fixes.push(`- ${firstLine.replace(/^fix[(]\s*/i, '')}`);
|
|
142
|
+
} else if (firstLine.match(/^doc(s)?[(]/i)) {
|
|
143
|
+
docs.push(`- ${firstLine.replace(/^doc(s)?[(]\s*/i, '')}`);
|
|
144
|
+
} else if (!firstLine.match(/^(chore|ci|test|build)[(:]/i)) {
|
|
145
|
+
chore.push(`- ${firstLine}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let notes = `## 🎉 Release ${{ steps.version.outputs.version }}\n\n`;
|
|
150
|
+
|
|
151
|
+
if (breaking.length > 0) {
|
|
152
|
+
notes += `### ⚠️ Breaking Changes\n${breaking.join('\n')}\n\n`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (features.length > 0) {
|
|
156
|
+
notes += `### ✨ Features\n${features.join('\n')}\n\n`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (fixes.length > 0) {
|
|
160
|
+
notes += `### 🐛 Bug Fixes\n${fixes.join('\n')}\n\n`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (docs.length > 0) {
|
|
164
|
+
notes += `### 📚 Documentation\n${docs.join('\n')}\n\n`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (chore.length > 0 && chore.length < 10) {
|
|
168
|
+
notes += `### 🔧 Other Changes\n${chore.join('\n')}\n\n`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
notes += `### 📦 Installation\n\n`;
|
|
172
|
+
notes += `\`\`\`bash\n`;
|
|
173
|
+
notes += `# npm\n`;
|
|
174
|
+
notes += `npm install -g httpcat-cli@${{ steps.version.outputs.version }}\n\n`;
|
|
175
|
+
notes += `# Homebrew\n`;
|
|
176
|
+
notes += `brew upgrade httpcat\n`;
|
|
177
|
+
notes += `\`\`\`\n\n`;
|
|
178
|
+
notes += `---\n\n`;
|
|
179
|
+
notes += `**Full Changelog**: https://github.com/${{ github.repository }}/compare/${lastTag || 'main'}...${currentTag}`;
|
|
180
|
+
|
|
181
|
+
core.setOutput('notes', notes);
|
|
182
|
+
console.log('Generated release notes');
|
|
183
|
+
|
|
184
|
+
# Job 2: Build and test
|
|
185
|
+
test:
|
|
186
|
+
name: Build & Test
|
|
187
|
+
runs-on: ubuntu-latest
|
|
188
|
+
needs: prepare
|
|
189
|
+
steps:
|
|
190
|
+
- name: Checkout code
|
|
191
|
+
uses: actions/checkout@v4
|
|
192
|
+
|
|
193
|
+
- name: Setup Node.js
|
|
194
|
+
uses: actions/setup-node@v4
|
|
195
|
+
with:
|
|
196
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
197
|
+
cache: 'yarn'
|
|
198
|
+
|
|
199
|
+
- name: Install dependencies
|
|
200
|
+
run: yarn install --frozen-lockfile
|
|
201
|
+
|
|
202
|
+
- name: Run linter (if configured)
|
|
203
|
+
continue-on-error: true
|
|
204
|
+
run: |
|
|
205
|
+
if [ -f ".eslintrc" ] || [ -f ".eslintrc.js" ] || [ -f ".eslintrc.json" ]; then
|
|
206
|
+
yarn lint
|
|
207
|
+
else
|
|
208
|
+
echo "No linter configured, skipping..."
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
- name: Run tests
|
|
212
|
+
run: yarn test
|
|
213
|
+
|
|
214
|
+
- name: Build
|
|
215
|
+
run: yarn build
|
|
216
|
+
|
|
217
|
+
- name: Verify build output
|
|
218
|
+
run: |
|
|
219
|
+
if [ ! -f "dist/index.js" ]; then
|
|
220
|
+
echo "❌ Build failed: dist/index.js not found"
|
|
221
|
+
exit 1
|
|
222
|
+
fi
|
|
223
|
+
echo "✅ Build successful"
|
|
224
|
+
|
|
225
|
+
# Job 3: Publish to npm
|
|
226
|
+
publish-npm:
|
|
227
|
+
name: Publish to npm
|
|
228
|
+
runs-on: ubuntu-latest
|
|
229
|
+
needs: [prepare, test]
|
|
230
|
+
environment:
|
|
231
|
+
name: npm-publish
|
|
232
|
+
url: https://www.npmjs.com/package/httpcat-cli
|
|
233
|
+
permissions:
|
|
234
|
+
contents: read
|
|
235
|
+
id-token: write # For npm provenance
|
|
236
|
+
steps:
|
|
237
|
+
- name: Checkout code
|
|
238
|
+
uses: actions/checkout@v4
|
|
239
|
+
|
|
240
|
+
- name: Setup Node.js
|
|
241
|
+
uses: actions/setup-node@v4
|
|
242
|
+
with:
|
|
243
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
244
|
+
registry-url: ${{ env.REGISTRY_URL }}
|
|
245
|
+
|
|
246
|
+
- name: Update package.json version
|
|
247
|
+
run: |
|
|
248
|
+
npm version "${{ needs.prepare.outputs.version }}" --no-git-tag-version --allow-same-version
|
|
249
|
+
|
|
250
|
+
- name: Install dependencies
|
|
251
|
+
run: yarn install --frozen-lockfile
|
|
252
|
+
|
|
253
|
+
- name: Build
|
|
254
|
+
run: yarn build
|
|
255
|
+
|
|
256
|
+
- name: Publish to npm
|
|
257
|
+
run: npm publish --provenance --access public
|
|
258
|
+
env:
|
|
259
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
260
|
+
|
|
261
|
+
- name: Verify npm publication
|
|
262
|
+
run: |
|
|
263
|
+
sleep 5 # Wait for npm CDN propagation
|
|
264
|
+
VERSION="${{ needs.prepare.outputs.version }}"
|
|
265
|
+
if npm view httpcat-cli@$VERSION version > /dev/null 2>&1; then
|
|
266
|
+
echo "✅ Successfully published httpcat-cli@$VERSION to npm"
|
|
267
|
+
else
|
|
268
|
+
echo "❌ Failed to verify npm publication"
|
|
269
|
+
exit 1
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
# Job 4: Update Homebrew formula
|
|
273
|
+
update-homebrew:
|
|
274
|
+
name: Update Homebrew Formula
|
|
275
|
+
runs-on: ubuntu-latest
|
|
276
|
+
needs: [prepare, publish-npm]
|
|
277
|
+
steps:
|
|
278
|
+
- name: Checkout code
|
|
279
|
+
uses: actions/checkout@v4
|
|
280
|
+
with:
|
|
281
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
282
|
+
|
|
283
|
+
- name: Wait for npm CDN propagation
|
|
284
|
+
run: |
|
|
285
|
+
VERSION="${{ needs.prepare.outputs.version }}"
|
|
286
|
+
echo "Waiting for npm package to be available..."
|
|
287
|
+
for i in {1..30}; do
|
|
288
|
+
if npm view httpcat-cli@$VERSION version > /dev/null 2>&1; then
|
|
289
|
+
echo "✅ Package is available on npm"
|
|
290
|
+
break
|
|
291
|
+
fi
|
|
292
|
+
echo "Attempt $i/30: Package not yet available, waiting 10s..."
|
|
293
|
+
sleep 10
|
|
294
|
+
done
|
|
295
|
+
|
|
296
|
+
- name: Get npm package SHA256
|
|
297
|
+
id: npm-sha
|
|
298
|
+
run: |
|
|
299
|
+
VERSION="${{ needs.prepare.outputs.version }}"
|
|
300
|
+
TARBALL_URL="https://registry.npmjs.org/httpcat-cli/-/httpcat-cli-${VERSION}.tgz"
|
|
301
|
+
|
|
302
|
+
echo "Downloading tarball to calculate SHA256..."
|
|
303
|
+
curl -L -o package.tgz "$TARBALL_URL"
|
|
304
|
+
SHA256=$(shasum -a 256 package.tgz | cut -d' ' -f1)
|
|
305
|
+
echo "sha256=$SHA256" >> $GITHUB_OUTPUT
|
|
306
|
+
echo "✅ SHA256: $SHA256"
|
|
307
|
+
|
|
308
|
+
- name: Update Homebrew formula
|
|
309
|
+
run: |
|
|
310
|
+
VERSION="${{ needs.prepare.outputs.version }}"
|
|
311
|
+
SHA256="${{ steps.npm-sha.outputs.sha256 }}"
|
|
312
|
+
FORMULA_FILE="homebrew-httpcat/Formula/httpcat.rb"
|
|
313
|
+
|
|
314
|
+
# Update version
|
|
315
|
+
sed -i.bak "s|url \".*httpcat-cli-.*\.tgz\"|url \"https://registry.npmjs.org/httpcat-cli/-/httpcat-cli-${VERSION}.tgz\"|" "$FORMULA_FILE"
|
|
316
|
+
|
|
317
|
+
# Update SHA256
|
|
318
|
+
sed -i.bak "s|sha256 \".*\"|sha256 \"${SHA256}\"|" "$FORMULA_FILE"
|
|
319
|
+
|
|
320
|
+
# Update test version
|
|
321
|
+
sed -i.bak "s|assert_match \".*\"|assert_match \"${VERSION}\"|" "$FORMULA_FILE"
|
|
322
|
+
|
|
323
|
+
rm -f "${FORMULA_FILE}.bak"
|
|
324
|
+
|
|
325
|
+
echo "✅ Updated Homebrew formula:"
|
|
326
|
+
cat "$FORMULA_FILE"
|
|
327
|
+
|
|
328
|
+
- name: Commit and push Homebrew formula update
|
|
329
|
+
run: |
|
|
330
|
+
git config user.name "github-actions[bot]"
|
|
331
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
332
|
+
git add homebrew-httpcat/Formula/httpcat.rb
|
|
333
|
+
git commit -m "chore: update Homebrew formula to v${{ needs.prepare.outputs.version }}" || exit 0
|
|
334
|
+
git push
|
|
335
|
+
|
|
336
|
+
# Job 5: Create GitHub Release
|
|
337
|
+
create-release:
|
|
338
|
+
name: Create GitHub Release
|
|
339
|
+
runs-on: ubuntu-latest
|
|
340
|
+
needs: [prepare, publish-npm, update-homebrew]
|
|
341
|
+
permissions:
|
|
342
|
+
contents: write
|
|
343
|
+
steps:
|
|
344
|
+
- name: Create GitHub Release
|
|
345
|
+
uses: softprops/action-gh-release@v1
|
|
346
|
+
with:
|
|
347
|
+
tag_name: ${{ needs.prepare.outputs.tag }}
|
|
348
|
+
name: Release ${{ needs.prepare.outputs.version }}
|
|
349
|
+
body: ${{ needs.prepare.outputs.release-notes }}
|
|
350
|
+
draft: false
|
|
351
|
+
prerelease: ${{ contains(needs.prepare.outputs.version, '-') }}
|
|
352
|
+
env:
|
|
353
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
354
|
+
|
|
355
|
+
- name: Release summary
|
|
356
|
+
run: |
|
|
357
|
+
echo "✅ Release created successfully!"
|
|
358
|
+
echo "Tag: ${{ needs.prepare.outputs.tag }}"
|
|
359
|
+
echo "Version: ${{ needs.prepare.outputs.version }}"
|
|
360
|
+
echo "npm: https://www.npmjs.com/package/httpcat-cli/v/${{ needs.prepare.outputs.version }}"
|
|
361
|
+
echo "GitHub: https://github.com/${{ github.repository }}/releases/tag/${{ needs.prepare.outputs.tag }}"
|