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
43 changes: 43 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!--
PR workflow reminder:
- Use a clear, outcome-focused title (this becomes a release note entry)
- Apply appropriate labels (e.g. enhancement, documentation, bug)
- Reference related issues using `Refs #NN` or `Fixes #NN`
- Squash merge is preferred unless stated otherwise
-->

## Summary

<!--
Briefly describe *what outcome this PR delivers*.
Think in terms of behavior, workflow, or guarantees — not implementation steps.
Explain the **WHY**, not the **HOW**.
-->

## Related Issues

<!--
Use one of:
- Refs #NN (contributes to an issue, prefer to close the issue manually if finished)
- Fixes #NN (closes an issue on merge)
-->

Refs #

## Changes

<!--
High-level bullets only. Avoid commit-level detail.
Use bullets, not paragraphs.
-->

-
-
-

## Further Comments

<!--
Optional context: testing notes, migration steps, screenshots, or anything
reviewers should know that doesn't fit above.
-->
38 changes: 38 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
changelog:
exclude:
labels:
- duplicate
- good-first-issue
- help-wanted
- invalid
- question
- wont-fix

categories:
- title: "Breaking Changes"
labels:
- breaking-change

- title: "Security"
labels:
- security

- title: "Enhancements"
labels:
- enhancement

- title: "Bug Fixes"
labels:
- bug

- title: "Documentation"
labels:
- documentation

- title: "Dependencies"
labels:
- dependencies

- title: "Other Changes"
labels:
- "*"
14 changes: 9 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,24 @@ jobs:
exit 1
fi

# Compute checksums from inside dist/ so the paths in checksums.txt don't include the dist/ prefix.
(cd dist && sha256sum $files) | sort > checksums.txt
# Compute checksums: format is "filename checksum" (filename first, stripped of artifact directory)
(cd dist && sha256sum $files) | while read sum file; do
echo "$(basename "$file") $sum"
done | sort > checksums.txt

echo ""
echo "checksums.txt:"
cat checksums.txt

- name: Prepare release notes
- name: Prepare checksums body
shell: bash
run: |
set -euo pipefail

{
echo "Automated release for v${{ needs.validate.outputs.version }}."
echo ""
echo "SHA256 checksums:"
echo "## SHA256 Checksums"
echo ""
echo '```'
cat checksums.txt
echo '```'
Expand All @@ -147,6 +149,8 @@ jobs:
uses: softprops/action-gh-release@v2
with:
name: "keystone-cli v${{ needs.validate.outputs.version }}"
generate_release_notes: true
append_body: true
body_path: release-body.md
files: |
dist/**/keystone-cli_${{ needs.validate.outputs.version }}_*.tar.gz
Expand Down
41 changes: 41 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,20 @@ keystone-cli/
├── tests/
│ └── Keystone.Cli.UnitTests/ # Unit tests mirroring src structure
├── docs/
│ ├── how-to/ # Procedural guides
│ │ ├── how-to-release.md # Release process documentation
│ │ ├── how-to-test-man-page.md # Man page testing guide
│ │ └── how-to-workflow.md # Development workflow guide
│ └── man/ # Manual pages in mdoc format
├── .github/
│ ├── workflows/ # GitHub Actions
│ │ ├── ci.yml # CI pipeline (tests on PR/push)
│ │ ├── release.yml # Release build and publish
│ │ └── tag-release.yml # Manual tag creation workflow
│ ├── pull_request_template.md # PR template
│ └── release.yml # Release notes configuration
├── scripts/ # Build and utility scripts
│ └── package-release.sh # Tarball packaging script
├── artifacts/ # Build outputs
├── Directory.Build.props # MSBuild configuration
└── keystone-cli.sln # Visual Studio solution
Expand Down Expand Up @@ -164,3 +176,32 @@ Tests mirror the source structure in `tests/Keystone.Cli.UnitTests/`:
- Self-contained single-file publishing enabled
- Deterministic builds for CI/CD
- Centralized build outputs in `artifacts/` directory

## CI/CD and Release Process

### GitHub Workflows

- **ci.yml**: Runs unit tests on PRs and pushes to main
- **tag-release.yml**: Manual workflow to create a version tag from csproj version
- **release.yml**: Triggered by `v*.*.*` tags; validates version, builds multi-platform
binaries, generates checksums, and publishes GitHub Release

### Release Flow

1. Update version using `/version X.Y.Z` command (updates csproj, man page, and tests)
2. Create PR and merge to main
3. Run `tag-release.yml` workflow manually (creates and pushes tag)
4. `release.yml` triggers automatically on tag push
5. Release published with binaries for osx-arm64, osx-x64, linux-x64, linux-arm64, etc.

### GitHub Configuration

- **release.yml** (in `.github/`): Configures auto-generated release notes categories
(Breaking Changes, Security, Enhancements, Bug Fixes, Documentation, Dependencies)
- **pull_request_template.md**: PR template enforcing outcome-focused descriptions and
label requirements

### Scripts

- **package-release.sh**: Creates release tarballs with binary, config, and man page;
generates SHA256 checksums. Usage: `./scripts/package-release.sh [version] [rid]`
33 changes: 3 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,39 +44,12 @@ man keystone-cli

The project is organized into four main parts:

- [docs](docs) – Contains documentation files, including man pages in [mdoc(7)](https://man.openbsd.org/mdoc.7)
- [docs](docs) – Contains how-tos, documentation files, including man pages in [mdoc(7)](https://man.openbsd.org/mdoc.7)
format and other relevant documentation.
- [scripts](scripts) – Build and utility scripts.
- [src](src) – Application source code.
- [tests](tests) – Unit tests organized to mirror the structure of the application for consistency and
coverage.

## Testing the Man Page

All examples assume you're in the root directory of the project.

Man pages use the [mdoc(7)](https://man.openbsd.org/mdoc.7) format -- a semantic markup language designed specifically
for writing Unix manual pages. While the `man` command can be used to view them, the `mandoc` utility is preferred for
local testing and rendering.

To read the [mdoc(7)](https://man.openbsd.org/mdoc.7) documentation in your terminal:

```bash
man 7 mdoc
```

### Using `mandoc`

To test the generated man page locally:

```bash
mandoc docs/man/man1/keystone-cli.1
```

### Using `man`

To view the man page with man, you must supply an absolute path for the man path:

```bash
man -M "$(cd docs/man && pwd)" keystone-cli
```
Review the contents of [docs/how-to](docs/how-to) for detailed guides on working with the project, contributing,
and releasing new versions.
File renamed without changes.
29 changes: 29 additions & 0 deletions docs/how-to/how-to-test-man-page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Testing the Man Page

All examples assume you're in the root directory of the project.

Man pages use the [mdoc(7)](https://man.openbsd.org/mdoc.7) format -- a semantic markup language designed specifically
for writing Unix manual pages. While the `man` command can be used to view them, the `mandoc` utility is preferred for
local testing and rendering.

To read the [mdoc(7)](https://man.openbsd.org/mdoc.7) documentation in your terminal:

```bash
man 7 mdoc
```

### Using `mandoc`

To test the generated man page locally:

```bash
mandoc docs/man/man1/keystone-cli.1
```

### Using `man`

To view the man page with man, you must supply an absolute path for the man path:

```bash
man -M "$(cd docs/man && pwd)" keystone-cli
```
68 changes: 68 additions & 0 deletions docs/how-to/how-to-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Workflow

This document outlines the project workflow. It describes the main steps and tasks required to ensure a smooth
and efficient process.

## Issue and Change Tracking Workflow

This project uses GitHub Issues and Pull Requests to track work and generate meaningful release notes with minimal
overhead. GitHub's default labels are used and intentionally kept unchanged.

### 1. Creating an Issue (Ticket)

Create a GitHub Issue for any user-visible change, bug, or non-trivial refactor worth tracking.

- Use a clear, outcome-focused title
- Add a short description explaining the problem or goal
- Apply one or more of GitHub's predefined labels as appropriate:
- `bug` – something is broken
- `enhancement` – new feature or improvement
- `documentation` – docs-related changes
- `question` – clarification or discussion

Issues act as lightweight tickets and historical context.

### 2. Working on an Issue

- Create a branch for the work (naming is flexible but should be descriptive)
- Implement the change
- Commit freely during development

Branch naming is optional and does not affect automation.

### 3. Opening a Pull Request

Open a Pull Request when the work is ready for review or merge.

- The PR title **must be release-note quality** (it will appear verbatim in release notes)
- The PR description should reference the issue using one of the following:
- `Fixes #<issue-number>` – closes the issue when merged
- `Refs #<issue-number>` – links the issue without closing it

Apply the same predefined label(s) used on the issue to the Pull Request.

### 4. Merging

- Prefer **squash merges** to keep history and release notes clean
- Ensure all required checks pass
- Avoid direct commits to the main branch

The merged PR title becomes the primary entry in the next release notes.

### 5. Releasing

For more information, see [How to release](how-to-release.md).

- When ready to ship, run the **Tag release** workflow manually
- This workflow creates a version tag
- Pushing the tag automatically triggers the Release workflow

Release notes are generated automatically from merged Pull Requests since the previous tag.

### 6. Release Notes Generation

- Release notes are PR-first and grouped by labels
- Only merged Pull Requests are included
- Issues are linked via PR references (no manual curation required)

This keeps releases fully automated while preserving traceability and clarity.