Skip to content

Commit af6c89a

Browse files
authored
Merge pull request #19 from kernel/release-please--branches--main--changes--next--components--hypeman
release: 0.6.0
2 parents fee5343 + c46e332 commit af6c89a

20 files changed

Lines changed: 506 additions & 38 deletions

.github/workflows/release-please.yml

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
name: Release Please
2+
3+
# `next` accumulates validated SDK changes in one versioned PR to `main`.
4+
# Merging that PR creates the GitHub release; the package publishing workflow
5+
# runs from the release event.
26
on:
37
push:
48
branches:
9+
- next
510
- main
611

712
permissions:
813
contents: read
914

15+
concurrency:
16+
group: release-please
17+
cancel-in-progress: false
18+
1019
jobs:
1120
release-please:
1221
if: github.repository == 'kernel/hypeman-ts'
@@ -26,7 +35,68 @@ jobs:
2635
permission-pull-requests: write
2736
permission-workflows: write
2837

29-
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
30-
id: release
38+
- name: Set up Node
39+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
40+
with:
41+
node-version: '18.20.2'
42+
43+
- name: Set up pnpm
44+
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
3145
with:
32-
token: ${{ steps.release-token.outputs.token }}
46+
version: '9.11.0'
47+
run_install: false
48+
49+
- name: Build pinned release tooling
50+
id: tooling
51+
env:
52+
RELEASE_PLEASE_DIR: ${{ runner.temp }}/release-please
53+
RELEASE_PLEASE_SHA: a116e1e520e0f87824acf46a2e79c91d41e819d7
54+
run: |
55+
set -euo pipefail
56+
rm -rf "$RELEASE_PLEASE_DIR"
57+
git init "$RELEASE_PLEASE_DIR"
58+
git -C "$RELEASE_PLEASE_DIR" remote add origin https://github.com/stainless-api/release-please.git
59+
git -C "$RELEASE_PLEASE_DIR" fetch --depth=1 origin "$RELEASE_PLEASE_SHA"
60+
git -C "$RELEASE_PLEASE_DIR" checkout --detach FETCH_HEAD
61+
pnpm --dir "$RELEASE_PLEASE_DIR" install --frozen-lockfile
62+
pnpm --dir "$RELEASE_PLEASE_DIR" build
63+
echo "cli=$RELEASE_PLEASE_DIR/build/src/bin/release-please.js" >> "$GITHUB_OUTPUT"
64+
65+
- name: Open or update the release PR
66+
if: github.ref_name == 'next'
67+
env:
68+
GH_TOKEN: ${{ steps.release-token.outputs.token }}
69+
RELEASE_PLEASE: ${{ steps.tooling.outputs.cli }}
70+
run: |
71+
set -euo pipefail
72+
node "$RELEASE_PLEASE" release-pr \
73+
--repo-url "$GITHUB_REPOSITORY" \
74+
--token "$GH_TOKEN" \
75+
--target-branch main \
76+
--changes-branch next
77+
78+
- name: Remove the legacy promotion PR
79+
if: github.ref_name == 'next'
80+
env:
81+
GH_TOKEN: ${{ steps.release-token.outputs.token }}
82+
run: |
83+
set -euo pipefail
84+
legacy=$(gh pr list --repo "$GITHUB_REPOSITORY" --head stainless/release \
85+
--state open --json number --jq '.[].number')
86+
for pr in $legacy; do
87+
gh pr close "$pr" --repo "$GITHUB_REPOSITORY" \
88+
--comment "Superseded by the versioned release PR from next to main."
89+
done
90+
gh api -X DELETE "repos/$GITHUB_REPOSITORY/git/refs/heads/stainless/release" >/dev/null 2>&1 || true
91+
92+
- name: Create the GitHub release
93+
if: github.ref_name == 'main'
94+
env:
95+
GH_TOKEN: ${{ steps.release-token.outputs.token }}
96+
RELEASE_PLEASE: ${{ steps.tooling.outputs.cli }}
97+
run: |
98+
set -euo pipefail
99+
node "$RELEASE_PLEASE" github-release \
100+
--repo-url "$GITHUB_REPOSITORY" \
101+
--token "$GH_TOKEN" \
102+
--target-branch main

.github/workflows/stlc-promote.yml

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
name: Promote SDKs
1+
name: Promote SDK changes
22

3-
# Manually fast-forwards production main to the reviewed staging main. The
4-
# ancestor check refuses divergent histories; this workflow never force-pushes.
3+
# Staging is the generator's integration history. Production `next` is the
4+
# developer-facing queue for the next release. This workflow combines the
5+
# latest released state with validated staging changes, then advances `next`.
6+
# Release automation maintains the single versioned PR from `next` to `main`.
57
on:
8+
push:
9+
branches: [main]
610
workflow_dispatch: {}
711

812
permissions:
@@ -12,7 +16,9 @@ jobs:
1216
promote:
1317
if: github.repository == 'kernel/hypeman-ts-staging'
1418
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
15-
environment: production
19+
concurrency:
20+
group: stlc-promote
21+
cancel-in-progress: true
1622
steps:
1723
- name: Check out staging
1824
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -29,33 +35,99 @@ jobs:
2935
owner: kernel
3036
repositories: hypeman-ts
3137
permission-contents: write
38+
permission-pull-requests: write
3239
permission-workflows: write
3340

34-
- name: Fetch production main
41+
- name: Fetch production branches
42+
id: production
3543
env:
3644
GH_TOKEN: ${{ steps.production-token.outputs.token }}
3745
PRODUCTION_REPO: kernel/hypeman-ts
3846
run: |
39-
git remote add production "https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git"
47+
set -euo pipefail
48+
git remote add production \
49+
"https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git"
4050
git fetch production main
41-
42-
- name: Check whether production already has staging's content
43-
id: diff
44-
run: |
45-
MERGED=$(git merge-tree --write-tree production/main origin/main) || MERGED=conflict
46-
PRODUCTION_TREE=$(git rev-parse 'production/main^{tree}')
47-
if [ "$MERGED" = "$PRODUCTION_TREE" ]; then
48-
echo "Production already contains staging's content. Nothing to promote."
49-
echo "synced=true" >> "$GITHUB_OUTPUT"
51+
if git ls-remote --exit-code --heads production next >/dev/null 2>&1; then
52+
git fetch production next
53+
echo "has_next=true" >> "$GITHUB_OUTPUT"
5054
else
51-
echo "synced=false" >> "$GITHUB_OUTPUT"
55+
echo "has_next=false" >> "$GITHUB_OUTPUT"
5256
fi
5357
54-
- name: Promote staging to production
55-
if: steps.diff.outputs.synced == 'false'
58+
- name: Prepare the next release branch
59+
env:
60+
APP_SLUG: ${{ steps.production-token.outputs.app-slug }}
61+
GH_TOKEN: ${{ steps.production-token.outputs.token }}
62+
HAS_NEXT: ${{ steps.production.outputs.has_next }}
63+
PRODUCTION_REPO: kernel/hypeman-ts
5664
run: |
57-
if ! git merge-base --is-ancestor production/main origin/main; then
58-
echo "::error title=Promote blocked::production/main is not an ancestor of staging main. Back-sync production first."
65+
set -euo pipefail
66+
bot_id=$(gh api "/users/${APP_SLUG}[bot]" --jq .id)
67+
git config user.name "${APP_SLUG}[bot]"
68+
git config user.email "${bot_id}+${APP_SLUG}[bot]@users.noreply.github.com"
69+
70+
open_conflict_pr() {
71+
source_ref=$1
72+
source_name=$2
73+
advance_next=$3
74+
conflict_branch=stlc/promotion-conflict
75+
76+
git merge --abort
77+
existing=$(gh pr list --repo "$PRODUCTION_REPO" --base next \
78+
--head "$conflict_branch" --state open --json url --jq '.[0].url // ""')
79+
if [ -n "$existing" ]; then
80+
echo "::error title=SDK promotion blocked::Resolve the existing recovery PR: $existing"
81+
exit 1
82+
fi
83+
84+
if [ "$advance_next" = "true" ]; then
85+
git push production HEAD:refs/heads/next
86+
fi
87+
git push production "$source_ref:refs/heads/$conflict_branch" --force
88+
89+
body=$(mktemp)
90+
printf '%s\n' \
91+
'## SDK promotion conflict' \
92+
'' \
93+
"The automated promotion could not merge $source_name into the pending next release." \
94+
'' \
95+
'Resolve the conflicts on this branch, validate the SDK, mark this PR ready, and merge it with a merge commit.' \
96+
'' \
97+
'After merging, rerun the staging Promote SDK changes workflow to include any newer generated changes.' \
98+
> "$body"
99+
recovery_url=$(gh pr create --repo "$PRODUCTION_REPO" --draft \
100+
--base next --head "$conflict_branch" \
101+
--title 'chore: resolve SDK promotion conflict' --body-file "$body")
102+
echo "::error title=SDK promotion conflict::Resolve the recovery PR: $recovery_url"
59103
exit 1
104+
}
105+
106+
if [ "$HAS_NEXT" = "true" ]; then
107+
git checkout -B stlc/promote-next production/next
108+
else
109+
git checkout -B stlc/promote-next production/main
110+
fi
111+
112+
if ! git merge-base --is-ancestor production/main HEAD; then
113+
if ! git merge --no-edit production/main; then
114+
open_conflict_pr production/main 'production main' false
115+
fi
116+
fi
117+
if ! git merge-base --is-ancestor origin/main HEAD; then
118+
if ! git merge --no-edit origin/main; then
119+
open_conflict_pr origin/main 'validated staging changes' true
120+
fi
121+
fi
122+
123+
if [ "$HAS_NEXT" = "true" ]; then
124+
git merge-base --is-ancestor production/next HEAD
60125
fi
61-
git push production origin/main:refs/heads/main
126+
127+
- name: Update the pending release
128+
env:
129+
GH_TOKEN: ${{ steps.production-token.outputs.token }}
130+
run: |
131+
set -euo pipefail
132+
git push production HEAD:refs/heads/next
133+
echo "Updated production next; the versioned release PR will be opened or refreshed."

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.5.1"
2+
".": "0.6.0"
33
}

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
configured_endpoints: 58
1+
configured_endpoints: 61

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [0.6.0](https://github.com/kernel/hypeman-ts/compare/v0.5.1...v0.6.0) (2026-08-12)
4+
5+
6+
### Features
7+
8+
* Add QEMU microvm hypervisor backend ([f8c18cf](https://github.com/kernel/hypeman-ts/commit/f8c18cf81953831bf2464f08c9e19a918ffdfb0c))
9+
* Add request header authorization to ingress rules ([2fb6855](https://github.com/kernel/hypeman-ts/commit/2fb68550870bace083b8636cc32e5d92255e527b))
10+
* chore(stlc): seal custom-code tracking files ([fd74279](https://github.com/kernel/hypeman-ts/commit/fd74279abdea5b466a4c5b031150aba1b0d0cdc0))
11+
312
## 0.5.1 (2026-08-06)
413

514
Full Changelog: [v0.5.0...v0.5.1](https://github.com/kernel/hypeman-ts/compare/v0.5.0...v0.5.1)

api.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,19 @@ Methods:
221221
- <code title="delete /builds/{id}">client.builds.<a href="./src/resources/builds.ts">cancel</a>(id) -> void</code>
222222
- <code title="get /builds/{id}/events">client.builds.<a href="./src/resources/builds.ts">events</a>(id, { ...params }) -> BuildEvent</code>
223223
- <code title="get /builds/{id}">client.builds.<a href="./src/resources/builds.ts">get</a>(id) -> Build</code>
224+
225+
# Pushes
226+
227+
Types:
228+
229+
- <code><a href="./src/resources/pushes.ts">CreatePushRequest</a></code>
230+
- <code><a href="./src/resources/pushes.ts">Push</a></code>
231+
- <code><a href="./src/resources/pushes.ts">PushCredentials</a></code>
232+
- <code><a href="./src/resources/pushes.ts">PushStatus</a></code>
233+
- <code><a href="./src/resources/pushes.ts">PushListResponse</a></code>
234+
235+
Methods:
236+
237+
- <code title="post /pushes">client.pushes.<a href="./src/resources/pushes.ts">create</a>({ ...params }) -> Push</code>
238+
- <code title="get /pushes">client.pushes.<a href="./src/resources/pushes.ts">list</a>() -> PushListResponse</code>
239+
- <code title="get /pushes/{id}">client.pushes.<a href="./src/resources/pushes.ts">get</a>(id) -> Push</code>

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@onkernel/hypeman",
3-
"version": "0.5.1",
3+
"version": "0.6.0",
44
"description": "The official TypeScript library for the Hypeman API",
55
"author": "Hypeman <>",
66
"types": "dist/index.d.ts",

release-please-config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"bump-minor-pre-major": true,
1111
"bump-patch-for-minor-pre-major": false,
1212
"pull-request-header": "Automated Release PR",
13+
"pull-request-footer": "Merge this pull request with a merge commit. Merging creates the GitHub release and publishes the package.",
1314
"pull-request-title-pattern": "release: ${version}",
1415
"changelog-sections": [
1516
{

src/client.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ import {
5959
IngressTarget,
6060
Ingresses,
6161
} from './resources/ingresses';
62+
import {
63+
CreatePushRequest,
64+
Push,
65+
PushCreateParams,
66+
PushCredentials,
67+
PushListResponse,
68+
PushStatus,
69+
Pushes,
70+
} from './resources/pushes';
6271
import {
6372
DiskBreakdown,
6473
GPUProfile,
@@ -850,6 +859,7 @@ export class Hypeman {
850859
resources: API.Resources = new API.Resources(this);
851860
builders: API.Builders = new API.Builders(this);
852861
builds: API.Builds = new API.Builds(this);
862+
pushes: API.Pushes = new API.Pushes(this);
853863
}
854864

855865
Hypeman.Health = Health;
@@ -861,6 +871,7 @@ Hypeman.Devices = Devices;
861871
Hypeman.Ingresses = Ingresses;
862872
Hypeman.Builders = Builders;
863873
Hypeman.Builds = Builds;
874+
Hypeman.Pushes = Pushes;
864875

865876
export declare namespace Hypeman {
866877
export type RequestOptions = Opts.RequestOptions;
@@ -987,5 +998,15 @@ export declare namespace Hypeman {
987998
type BuildEventsParams as BuildEventsParams,
988999
};
9891000

1001+
export {
1002+
Pushes as Pushes,
1003+
type CreatePushRequest as CreatePushRequest,
1004+
type Push as Push,
1005+
type PushCredentials as PushCredentials,
1006+
type PushStatus as PushStatus,
1007+
type PushListResponse as PushListResponse,
1008+
type PushCreateParams as PushCreateParams,
1009+
};
1010+
9901011
export type SnapshotCompressionConfig = API.SnapshotCompressionConfig;
9911012
}

0 commit comments

Comments
 (0)