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
51 changes: 51 additions & 0 deletions .agents/skills/release/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
name: release
description: Release harbor-hypeman to PyPI and GitHub. Use when asked to publish, release, cut a version, bump the package version, or verify a harbor-hypeman release.
---

# Release harbor-hypeman

Publish immutable releases from version tags on `main`. PyPI authentication uses the `pypi` GitHub environment and Trusted Publishing; never add an API token.

## Prepare the version

1. Fetch `origin` and require a clean working tree.
2. Read the version from `pyproject.toml` and the latest `v*` tag.
3. If the current version is already greater than the latest tag, use it. Otherwise create a `hypeship/release-vX.Y.Z` branch and update:
- `project.version` in `pyproject.toml`
- the matching package version in `uv.lock` by running `uv lock`
- `CHANGELOG.md`, moving relevant entries from `Unreleased` into a dated version section
4. Run:

```bash
uv sync --locked --dev
uv run ruff format --check .
uv run ruff check .
uv run ty check
uv run pytest
uv build
```

5. Commit, push, and open a ready-for-review release PR. Wait for required CI, BugBot, and review before merging.

## Publish

1. Return to `main`, fast-forward to `origin/main`, and verify the release workflow and version bump are present.
2. Require the release commit to be exactly `origin/main` and confirm the tag does not already exist locally or remotely.
3. Create and push an annotated tag:

```bash
git tag -a "vX.Y.Z" -m "Release vX.Y.Z"
git push origin "vX.Y.Z"
```

4. Watch the `Release` workflow until it succeeds. It verifies the tag and version, runs all checks, publishes with PyPI Trusted Publishing, and creates the GitHub release.
5. Verify both release surfaces:

```bash
gh release view "vX.Y.Z"
curl -fsSL https://pypi.org/pypi/harbor-hypeman/json | jq -e '.info.version == "X.Y.Z"'
uv run --isolated --with "harbor-hypeman==X.Y.Z" python -c 'import harbor_hypeman'
```

Never reuse a version already published to PyPI. If publication succeeded but a later step failed, repair that step without moving or recreating the tag.
59 changes: 59 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Release

on:
push:
tags:
- "v*"

permissions:
contents: read

concurrency:
group: release-${{ github.ref }}

jobs:
release:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/harbor-hypeman
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
with:
version: "0.12.3"
enable-cache: true
- run: uv python install 3.12
- name: Verify release tag
shell: bash
run: |
set -euo pipefail
[[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]
version=$(uv run --no-project --python 3.12 python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')
test "$GITHUB_REF_NAME" = "v$version"
git fetch origin main
test "$GITHUB_SHA" = "$(git rev-parse origin/main)"
- run: uv sync --locked --dev
- run: uv run ruff format --check .
- run: uv run ruff check .
- run: uv run ty check
- run: uv run pytest
- run: uv build
- name: Publish to PyPI
run: >-
uv publish
--trusted-publishing always
--check-url https://pypi.org/simple/harbor-hypeman/
- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: >-
gh release create "$GITHUB_REF_NAME" dist/*
--verify-tag
--generate-notes
--title "harbor-hypeman $GITHUB_REF_NAME"
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

All notable changes to this project are documented in this file.

## [Unreleased]

## [0.1.0] - 2026-08-17

### Added

- Hypeman environment backend for Harbor.
- Dockerfile builds and prebuilt container images.
- Instance lifecycle, command execution, and file transfer support.
- CPU, memory, storage, and network configuration.

[Unreleased]: https://github.com/kernel/harbor-hypeman/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/kernel/harbor-hypeman/releases/tag/v0.1.0
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ dependencies = [
"pathspec>=1.0.3",
]

[project.urls]
Repository = "https://github.com/kernel/harbor-hypeman"
Changelog = "https://github.com/kernel/harbor-hypeman/blob/main/CHANGELOG.md"

[dependency-groups]
dev = [
"pytest>=8.4.2",
Expand Down