Skip to content

Commit 6ec6d3e

Browse files
anandgupta42claude
andauthored
perf: optimize CI/CD pipeline with caching and parallel builds (#42)
* perf: optimize CI/CD pipeline with caching and parallel builds - Add Bun dependency caching to CI and Release workflows - Add pip caching to Python test, docs, and engine publish workflows - Separate lint into its own fast job (dev-only deps, no warehouses) - Split release binary builds into 3 parallel matrix jobs (linux/darwin/win32) - Add --targets flag to build.ts for OS-based target filtering - Remove unnecessary publish-npm dependency from GitHub Release job - Add concurrency control to release workflow Expected improvements: - Release: ~18min → ~8-9min (parallel builds + parallel publishing) - CI: faster repeat runs via dependency caching Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR review feedback - Restore github-release dependency on publish-npm to prevent partial releases where npm install instructions point to unpublished packages - Use `pip install ruff` in lint job instead of `.[dev]` for faster runs - Create docs/requirements.txt for proper pip cache invalidation - Add cache-dependency-path to publish-engine and release publish-engine - Validate --targets flag against known OS values (linux/darwin/win32) - Add comment documenting intentional publish-engine parallelism - Simplify concurrency group name Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8616a7e commit 6ec6d3e

File tree

6 files changed

+84
-14
lines changed

6 files changed

+84
-14
lines changed

.github/workflows/ci.yml

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ jobs:
1515

1616
- uses: oven-sh/setup-bun@v2
1717

18+
- name: Cache Bun dependencies
19+
uses: actions/cache@v4
20+
with:
21+
path: ~/.bun/install/cache
22+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
23+
restore-keys: |
24+
bun-${{ runner.os }}-
25+
1826
- name: Configure git for tests
1927
run: |
2028
git config --global user.name "CI"
@@ -27,6 +35,23 @@ jobs:
2735
run: bun test
2836
working-directory: packages/altimate-code
2937

38+
lint:
39+
name: Lint
40+
runs-on: ubuntu-latest
41+
steps:
42+
- uses: actions/checkout@v4
43+
44+
- uses: actions/setup-python@v5
45+
with:
46+
python-version: "3.12"
47+
48+
- name: Install linter
49+
run: pip install ruff
50+
51+
- name: Lint
52+
run: ruff check src
53+
working-directory: packages/altimate-engine
54+
3055
python:
3156
name: Python ${{ matrix.python-version }}
3257
runs-on: ubuntu-latest
@@ -39,6 +64,8 @@ jobs:
3964
- uses: actions/setup-python@v5
4065
with:
4166
python-version: ${{ matrix.python-version }}
67+
cache: 'pip'
68+
cache-dependency-path: packages/altimate-engine/pyproject.toml
4269

4370
- name: Install dependencies
4471
run: pip install -e ".[dev,warehouses]"
@@ -47,7 +74,3 @@ jobs:
4774
- name: Run tests
4875
run: pytest
4976
working-directory: packages/altimate-engine
50-
51-
- name: Lint
52-
run: ruff check src
53-
working-directory: packages/altimate-engine

.github/workflows/docs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ jobs:
2626
uses: actions/setup-python@v5
2727
with:
2828
python-version: "3.12"
29+
cache: "pip"
30+
cache-dependency-path: docs/requirements.txt
2931

3032
- name: Install mkdocs-material
3133
run: pip install mkdocs-material

.github/workflows/publish-engine.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818
- uses: actions/setup-python@v5
1919
with:
2020
python-version: "3.12"
21+
cache: "pip"
22+
cache-dependency-path: packages/altimate-engine/pyproject.toml
2123

2224
- name: Install build tools
2325
run: pip install build

.github/workflows/release.yml

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ on:
55
tags:
66
- "v*"
77

8+
concurrency:
9+
group: release
10+
cancel-in-progress: false
11+
812
permissions:
913
contents: write
1014
id-token: write
@@ -14,18 +18,30 @@ env:
1418

1519
jobs:
1620
build:
17-
name: Build
21+
name: Build (${{ matrix.os }})
1822
runs-on: ubuntu-latest
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
os: [linux, darwin, win32]
1927
steps:
2028
- uses: actions/checkout@v4
2129

2230
- uses: oven-sh/setup-bun@v2
2331

32+
- name: Cache Bun dependencies
33+
uses: actions/cache@v4
34+
with:
35+
path: ~/.bun/install/cache
36+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
37+
restore-keys: |
38+
bun-${{ runner.os }}-
39+
2440
- name: Install dependencies
2541
run: bun install
2642

27-
- name: Build all targets
28-
run: bun run packages/altimate-code/script/build.ts
43+
- name: Build ${{ matrix.os }} targets
44+
run: bun run packages/altimate-code/script/build.ts --targets=${{ matrix.os }}
2945
env:
3046
ALTIMATE_CLI_VERSION: ${{ github.ref_name }}
3147
ALTIMATE_CLI_CHANNEL: latest
@@ -36,7 +52,7 @@ jobs:
3652
- name: Upload build artifacts
3753
uses: actions/upload-artifact@v4
3854
with:
39-
name: dist
55+
name: dist-${{ matrix.os }}
4056
path: packages/altimate-code/dist/
4157

4258
publish-npm:
@@ -48,14 +64,23 @@ jobs:
4864

4965
- uses: oven-sh/setup-bun@v2
5066

67+
- name: Cache Bun dependencies
68+
uses: actions/cache@v4
69+
with:
70+
path: ~/.bun/install/cache
71+
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
72+
restore-keys: |
73+
bun-${{ runner.os }}-
74+
5175
- name: Install dependencies
5276
run: bun install
5377

54-
- name: Download build artifacts
78+
- name: Download all build artifacts
5579
uses: actions/download-artifact@v4
5680
with:
57-
name: dist
81+
pattern: dist-*
5882
path: packages/altimate-code/dist/
83+
merge-multiple: true
5984

6085
- name: Configure npm auth
6186
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
@@ -89,9 +114,10 @@ jobs:
89114
GH_REPO: ${{ env.GH_REPO }}
90115
GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
91116

117+
# Engine publish runs without waiting for build — it builds from source and
118+
# doesn't need CLI binary artifacts. This allows it to run in parallel.
92119
publish-engine:
93120
name: Publish engine to PyPI
94-
needs: build
95121
runs-on: ubuntu-latest
96122
environment: pypi
97123
permissions:
@@ -103,6 +129,8 @@ jobs:
103129
- uses: actions/setup-python@v5
104130
with:
105131
python-version: "3.12"
132+
cache: 'pip'
133+
cache-dependency-path: packages/altimate-engine/pyproject.toml
106134

107135
- name: Install build tools
108136
run: pip install build
@@ -177,11 +205,12 @@ jobs:
177205
GH_REPO: ${{ env.GH_REPO }}
178206
CURRENT_TAG: ${{ github.ref_name }}
179207

180-
- name: Download build artifacts
208+
- name: Download all build artifacts
181209
uses: actions/download-artifact@v4
182210
with:
183-
name: dist
211+
pattern: dist-*
184212
path: packages/altimate-code/dist/
213+
merge-multiple: true
185214

186215
- name: Create GitHub Release
187216
uses: softprops/action-gh-release@v2

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mkdocs-material

packages/altimate-code/script/build.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,17 @@ const allTargets: {
129129
},
130130
]
131131

132+
// If --targets is provided, filter to only matching OS values
133+
const validOsValues = new Set(allTargets.map(t => t.os))
134+
const targetsFlag = process.argv.find(a => a.startsWith('--targets='))?.split('=')[1]?.split(',')
135+
if (targetsFlag) {
136+
const invalid = targetsFlag.filter(t => !validOsValues.has(t))
137+
if (invalid.length > 0) {
138+
console.error(`error: invalid --targets value(s): ${invalid.join(', ')}. Valid values: ${[...validOsValues].join(', ')}`)
139+
process.exit(1)
140+
}
141+
}
142+
132143
const targets = singleFlag
133144
? allTargets.filter((item) => {
134145
if (item.os !== process.platform || item.arch !== process.arch) {
@@ -148,7 +159,9 @@ const targets = singleFlag
148159

149160
return true
150161
})
151-
: allTargets
162+
: targetsFlag
163+
? allTargets.filter(t => targetsFlag.includes(t.os))
164+
: allTargets
152165

153166
await $`rm -rf dist`
154167

0 commit comments

Comments
 (0)