Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions .claude/skills/npm-release/skill.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: npm-release
description: Bump @oxide/api to a new omicron release tag, open the PR, and (after the user merges and CI publishes) hand off the npm dist-tag command.
description: Bump @oxide/api to a new omicron release tag locally, then (after the user pushes, merges, and CI publishes) hand off the npm dist-tag command.
user_invocable: true
---

Expand Down Expand Up @@ -60,28 +60,24 @@ Ask the user for:
- `cd oxide-api && npm ci && npm run tsc`
- `cd oxide-openapi-gen-ts && npm run tsc && npm run lint && npm run fmt:check`

### Phase 2: PR
### Phase 2: Hand off (do not push)

8. **Create a branch and PR.** Use jj to create a new commit, then push a
branch and open a PR:
```
jj desc -m 'Bump API to <tag> (<version>)'
jj git push --change @
```
Then create the PR with `gh pr create`. Use a title like
`Bump API to rel/v19/rc0 (0.6.0)` and mention the omicron tag in the body.
8. **Describe the commit and stop.** Set the commit description with
`jj desc -m 'Bump API to <tag> (<version>)'` and leave the change in the
working copy for the user to review.

9. **Wait for CI.** The `update-api-spec` workflow runs on push to non-main
branches and may create an "Autogenerate config update" commit — this is
expected. The `validate` workflow must pass.
Do **not** push a branch, and do **not** open a PR. No `jj git push`, no
`gh pr create`. The user pushes and opens the PR themselves. Report what
changed (the files touched and any notable spec changes) and stop there.

10. **Hand off to the user for review and merge.** Once CI is green, report
that the PR is ready and stop. The user will review and merge the PR
themselves, then tell you to continue. Do not merge the PR yourself.
Note for when the PR does exist: the `update-api-spec` workflow runs on push
to non-main branches and may create an "Autogenerate config update" commit —
that is expected. The `validate` workflow must pass. The user reviews and
merges; never merge the PR yourself.

### Phase 3: Publish (automatic) and dist-tag (manual)

11. **Approve and wait for the automatic publish.** Merging the PR triggers the
9. **Approve and wait for the automatic publish.** Merging the PR triggers the
`Release` workflow on main, which runs validation and then waits for a
required reviewer to approve the `release` environment deployment. Tell
the user to approve it (or ask another required reviewer to approve it) in
Expand All @@ -92,7 +88,7 @@ Ask the user for:
and confirm with `npm view @oxide/api version`, which should show the new
version.

12. **Add npm dist-tag.** Tag the published version with the release name so
10. **Add npm dist-tag.** Tag the published version with the release name so
consumers can pin to it:
```
npm dist-tag add @oxide/api@<version> rel<N>
Expand Down
2 changes: 1 addition & 1 deletion OMICRON_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3e5bafe8ad9d19de5db48fb50bbe2e9437f82e86
667f7be3d3e4b1be1146cbb1e7b1cb134f49df05

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 change: 1 addition & 0 deletions oxide-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Make sure to use the SDK compatible with your Oxide system version.

| System version | `@oxide/api` version | npm tag |
| --- | --- | --- |
| [22](https://docs.oxide.computer/release-notes/system/22) | 0.9.0 | `rel22` |
| [21](https://docs.oxide.computer/release-notes/system/21) | 0.8.0 | `rel21` |
| [20](https://docs.oxide.computer/release-notes/system/20) | 0.7.0 | `rel20` |
| [19](https://docs.oxide.computer/release-notes/system/19) | 0.6.0 | `rel19` |
Expand Down
4 changes: 2 additions & 2 deletions oxide-api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion oxide-api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oxide/api",
"version": "0.8.0",
"version": "0.9.0",
"description": "TypeScript client for the Oxide API",
"engines": {
"node": ">=18"
Expand Down
106 changes: 47 additions & 59 deletions oxide-api/src/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3069,6 +3069,16 @@ export type InternetGatewayResultsPage = {
nextPage?: string | null;
};

/**
* Assignment of an IP pool to resources and services.
*/
export type IpPoolAssignment =
/** Pool is available to be linked to customer silos. */
| "silos"

/** Pool is reserved for Oxide-operated rack services (NTP, DNS, etc.). */
| "system_services";

/**
* Type of IP pool.
*/
Expand All @@ -3082,9 +3092,11 @@ All ranges in a multicast pool must be either ASM or SSM (not mixed). */
| "multicast";

/**
* A collection of IP ranges. If a pool is linked to a silo, IP addresses from the pool can be allocated within that silo.
* A collection of IP ranges.
*/
export type IpPool = {
/** What this pool is currently assigned to. */
assignment: IpPoolAssignment;
/** Human-readable free-form text about a resource */
description: string;
/** Unique, immutable, system-controlled identifier for each resource */
Expand All @@ -3101,6 +3113,11 @@ export type IpPool = {
timeModified: Date;
};

/**
* Body parameters for reassigning an IP pool.
*/
export type IpPoolAssignParam = { assignment: IpPoolAssignment };

/**
* Create-time parameters for an `IpPool`.
*
Expand All @@ -3109,6 +3126,8 @@ export type IpPool = {
* ASM: IPv4 addresses outside 232.0.0.0/8, IPv6 addresses with flag field != 3 SSM: IPv4 addresses in 232.0.0.0/8, IPv6 addresses with flag field = 3
*/
export type IpPoolCreate = {
/** What this pool is assigned to (defaults to Silos). */
assignment?: IpPoolAssignment;
description: string;
/** The IP version of the pool.

Expand Down Expand Up @@ -6633,8 +6652,10 @@ export interface InternetGatewayDeleteQueryParams {
}

export interface IpPoolListQueryParams {
ipVersion?: IpVersion;
limit?: number | null;
pageToken?: string | null;
poolType?: IpPoolType;
sortBy?: NameOrIdSortMode;
}

Expand Down Expand Up @@ -7024,8 +7045,11 @@ export interface SamlIdentityProviderViewQueryParams {
}

export interface SystemIpPoolListQueryParams {
assignment?: IpPoolAssignment;
ipVersion?: IpVersion;
limit?: number | null;
pageToken?: string | null;
poolType?: IpPoolType;
sortBy?: NameOrIdSortMode;
}

Expand All @@ -7041,6 +7065,10 @@ export interface SystemIpPoolDeletePathParams {
pool: NameOrId;
}

export interface SystemIpPoolAssignPathParams {
pool: NameOrId;
}

export interface SystemIpPoolRangeListPathParams {
pool: NameOrId;
}
Expand Down Expand Up @@ -7086,11 +7114,6 @@ export interface SystemIpPoolUtilizationViewPathParams {
pool: NameOrId;
}

export interface SystemIpPoolServiceRangeListQueryParams {
limit?: number | null;
pageToken?: string | null;
}

export interface SystemMetricPathParams {
metricName: SystemMetricName;
}
Expand Down Expand Up @@ -7659,7 +7682,7 @@ export class Api {
* Pulled from info.version in the OpenAPI schema. Sent in the
* `api-version` header on all requests.
*/
apiVersion = "2026061000.0.0";
apiVersion = "2026073100.0.0";

constructor({ host = "", baseParams = {}, token }: ApiConfig = {}) {
this.host = host;
Expand Down Expand Up @@ -10858,6 +10881,23 @@ export class Api {
...params,
});
},
/**
* Assign IP pool
*/
systemIpPoolAssign: (
{
path,
body,
}: { path: SystemIpPoolAssignPathParams; body: IpPoolAssignParam },
params: FetchParams = {},
) => {
return this.request<IpPool>({
path: `/v1/system/ip-pools/${path.pool}/assignment`,
method: "POST",
body,
...params,
});
},
/**
* List ranges for IP pool
*/
Expand Down Expand Up @@ -10989,58 +11029,6 @@ export class Api {
...params,
});
},
/**
* Fetch Oxide service IP pool
*/
systemIpPoolServiceView: (_: EmptyObj, params: FetchParams = {}) => {
return this.request<IpPool>({
path: `/v1/system/ip-pools-service`,
method: "GET",
...params,
});
},
/**
* List IP ranges for the Oxide service pool
*/
systemIpPoolServiceRangeList: (
{ query = {} }: { query?: SystemIpPoolServiceRangeListQueryParams },
params: FetchParams = {},
) => {
return this.request<IpPoolRangeResultsPage>({
path: `/v1/system/ip-pools-service/ranges`,
method: "GET",
query,
...params,
});
},
/**
* Add IP range to Oxide service pool
*/
systemIpPoolServiceRangeAdd: (
{ body }: { body: IpRange },
params: FetchParams = {},
) => {
return this.request<IpPoolRange>({
path: `/v1/system/ip-pools-service/ranges/add`,
method: "POST",
body,
...params,
});
},
/**
* Remove IP range from Oxide service pool
*/
systemIpPoolServiceRangeRemove: (
{ body }: { body: IpRange },
params: FetchParams = {},
) => {
return this.request<void>({
path: `/v1/system/ip-pools-service/ranges/remove`,
method: "POST",
body,
...params,
});
},
/**
* View metrics
*/
Expand Down
Loading
Loading