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
39 changes: 24 additions & 15 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,29 @@ jobs:
with:
fetch-depth: 0

- name: Generate release notes
id: release-notes
shell: pwsh
run: |
$releaseJson = gh release list `
--repo "$env:GITHUB_REPOSITORY" `
--limit 1 `
--json tagName
if ($LASTEXITCODE -ne 0) {
throw "Could not determine the previous release."
}
$releases = @($releaseJson | ConvertFrom-Json)
$previousTag = if ($releases.Count -gt 0) { $releases[0].tagName } else { "" }
$notesPath = Join-Path $env:RUNNER_TEMP "captail-$env:VERSION-release-notes.md"
./tools/New-ReleaseNotes.ps1 `
-Version $env:VERSION `
-PreviousTag $previousTag `
-Repository $env:GITHUB_REPOSITORY `
-OutputPath $notesPath
"path=$notesPath" >> $env:GITHUB_OUTPUT
env:
GH_TOKEN: ${{ github.token }}

- name: Set up .NET
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
with:
Expand Down Expand Up @@ -200,19 +223,6 @@ jobs:
- name: Publish GitHub Release
shell: pwsh
run: |
$intro = @"
> [!WARNING]
> Captail $env:VERSION is an early public preview. Bugs and hardware-specific issues are expected.

**Recommended:** download the Setup EXE. It includes Captail, .NET, and required libobs components and creates a Windows uninstaller.

**Portable:** extract the entire ZIP before launching `Captail.exe`.

Tested on NVIDIA GeForce RTX 40 and RTX 50 series. Older NVIDIA, AMD, and Intel hardware still needs broader public testing. Please report results and bugs through GitHub Issues.

Release binaries are not Authenticode-signed. Verify `SHA256SUMS.txt` and GitHub build provenance.
"@

$assets = @(
(Join-Path $env:RELEASE_DIR "Captail-$env:VERSION-Portable-win-x64.zip"),
(Join-Path $env:RELEASE_DIR "Captail-$env:VERSION-Setup-win-x64.exe"),
Expand All @@ -224,8 +234,7 @@ jobs:
"--repo", $env:GITHUB_REPOSITORY,
"--target", $env:GITHUB_SHA,
"--title", "Captail v$env:VERSION",
"--notes", $intro,
"--generate-notes"
"--notes-file", '${{ steps.release-notes.outputs.path }}'
)
if ('${{ inputs.prerelease }}' -eq 'true') {
$arguments += "--prerelease"
Expand Down
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,29 @@ All notable user-facing changes are documented here.

- Update downloads now close their file handles before promoting verified packages or replacing an invalid cached package, preventing Windows file-lock errors during one-click updates.

### Upgrade note
### Upgrade notes

- Captail 0.1.3 and 0.1.4 cannot complete an in-app update because the bug is inside those installed versions. Download and run the 0.1.5 Setup EXE once; later in-app updates will work normally.

## [0.1.4] - 2026-08-02

### Added

- Replay library with every saved clip in a vertically scrollable list.
- Built-in clip editor with responsive video preview, a single trim range, separate system/game and microphone track controls, save-as-copy, and confirmed overwrite.
- Clip details showing estimated trimmed size, original size, resolution, frame rate, and codec.
- Automatic desktop-to-game capture switching, plus a game-only mode that leaves the desktop out of recordings.

### Changed

- Replay cards now reveal compact actions on hover instead of using a large edge glow.
- FFmpeg and FFplay are included with Captail, so clip preview and trimming need no separate download.

### Fixed

- Clean installations now receive the FFmpeg runtime required by the editor.
- Preview rendering keeps the complete frame visible instead of showing only its upper-left region.

## [0.1.3] - 2026-07-26

### Added
Expand Down
91 changes: 91 additions & 0 deletions docs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Writing Captail release notes

Release notes answer three user questions:

1. What changed?
2. Why does it matter to me?
3. Must I do anything before or after updating?

`CHANGELOG.md` is the source for GitHub Release descriptions. The release workflow extracts the matching version section and adds package, compatibility, verification, and full-changelog links automatically.

## Before writing

Review every commit and merged pull request since the previous tag. For each user-visible change, record:

- what changed;
- which users or workflows it affects;
- the practical benefit or resolved problem;
- any required upgrade action;
- limitations that remain.

Do not infer a feature from a filename or commit title. Check the implementation, pull request description, or validation evidence.

## Required changelog format

Move completed entries from `[Unreleased]` into a version section before starting the release workflow:

```markdown
## [0.2.0] - 2026-08-15

### Added

- **Replay search:** Find saved clips by game or filename without browsing folders manually.

### Improved

- **Game detection:** Games are recognized sooner after launch, reducing desktop footage at the start of a clip.

### Fixed

- Fixed microphone audio disappearing after its device reconnects.

### Upgrade notes

- **Action required:** Install this version manually if updating from 0.1.3 or 0.1.4.
```

The version must match the workflow input exactly. Use `YYYY-MM-DD` for the date. Omit empty categories.

## Categories

- `Added`: new user-facing capabilities.
- `Improved`: an existing workflow became faster, clearer, or more capable.
- `Fixed`: a user-visible problem no longer occurs.
- `Upgrade notes`: users must take an action or should expect a one-time behavior.
- `Breaking changes`: existing settings, files, hotkeys, or workflows stop being compatible.
- `Known limitations`: important constraints still present in this release.

## Writing rules

- Lead with user impact, not implementation details.
- Use one bullet per change and keep it to one or two sentences.
- Use plain language. Explain technical terms only when users need them to act.
- Be specific about affected versions, capture modes, codecs, or hardware.
- Include measured performance only when the test setup and result are recorded.
- State uncertainty directly. Do not claim untested GPU or codec support.
- Do not paste commit titles, ticket numbers, validation logs, or dependency bumps into user notes.
- Do not describe routine refactoring unless it changes behavior, reliability, security, or performance.
- Do not use promotional claims such as “best,” “perfect,” or “production-ready.”

## Generate a local preview

```powershell
.\tools\New-ReleaseNotes.ps1 `
-Version 0.2.0 `
-PreviousTag v0.1.5 `
-OutputPath "$env:TEMP\captail-release-notes.md"

Get-Content "$env:TEMP\captail-release-notes.md"
```

Check that the preview:

- begins with the changes rather than build-system details;
- includes every required user action;
- contains no empty heading;
- uses correct package names and compare links;
- matches the English wording used in Captail.

## After publishing

Open the release page and confirm its version, text, assets, checksums, prerelease state, and full-changelog link. Never replace binaries under an existing tag; publish a new patch version instead.
27 changes: 26 additions & 1 deletion docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ Each release contains:

## Create a release

Before running the workflow:

1. Review changes since the previous tag.
2. Move completed entries from `[Unreleased]` into a dated version section in `CHANGELOG.md`.
3. Follow [RELEASE_NOTES.md](RELEASE_NOTES.md) for categories, wording, and required upgrade notices.
4. Preview the generated GitHub Release description locally:

```powershell
.\tools\New-ReleaseNotes.ps1 `
-Version 0.1.6 `
-PreviousTag v0.1.5 `
-OutputPath "$env:TEMP\captail-release-notes.md"
```

Commit and merge the changelog before dispatching the release. The workflow stops if it cannot find a non-empty section matching the requested version.

Then start the release from GitHub:

From GitHub:

1. Open **Actions**.
Expand All @@ -29,7 +47,14 @@ gh workflow run release.yml `
-f prerelease=true
```

The workflow validates the version, builds and verifies both packages, creates tag `v0.1.1`, and publishes the GitHub Release.
The workflow validates the version, builds and verifies both packages, creates tag `v0.1.1`, and publishes the GitHub Release using the matching changelog section.

After publishing, verify:

- release title, version, and prerelease status;
- Installer, Portable ZIP, and `SHA256SUMS.txt` assets;
- generated release notes and full-changelog link;
- GitHub build-provenance attestations.

## Local package build

Expand Down
78 changes: 78 additions & 0 deletions tools/New-ReleaseNotes.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[ValidatePattern('^\d+\.\d+\.\d+$')]
[string]$Version,

[Parameter(Mandatory)]
[string]$OutputPath,

[string]$ChangelogPath = "",

[string]$Repository = "FaulMit/captail",

[string]$PreviousTag = ""
)

$ErrorActionPreference = "Stop"
$repoRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot ".."))
if (-not $ChangelogPath) {
$ChangelogPath = Join-Path $repoRoot "CHANGELOG.md"
}

if (-not (Test-Path -LiteralPath $ChangelogPath -PathType Leaf)) {
throw "Changelog not found: $ChangelogPath"
}

$changelog = Get-Content -LiteralPath $ChangelogPath -Raw
$escapedVersion = [Regex]::Escape($Version)
$pattern = "(?ms)^## \[$escapedVersion\] - (?<date>\d{4}-\d{2}-\d{2})\r?\n(?<body>.*?)(?=^## \[|\z)"
$match = [Regex]::Match($changelog, $pattern)
if (-not $match.Success) {
throw "CHANGELOG.md has no release section for [$Version]."
}

$changeBody = $match.Groups["body"].Value.Trim()
if (-not $changeBody) {
throw "CHANGELOG.md release section [$Version] is empty."
}

# Changelog entries are nested below version headings. Promote their headings
# one level when the entry becomes a standalone GitHub Release description.
$changeBody = [Regex]::Replace($changeBody, '(?m)^### ', '## ')

$lines = [Collections.Generic.List[string]]::new()
$lines.Add("> [!WARNING]")
$lines.Add("> Captail $Version is an early public preview. Bugs and hardware-specific issues are expected.")
$lines.Add("")
$lines.Add($changeBody)
$lines.Add("")
$lines.Add("## Downloads")
$lines.Add("")
$lines.Add("- **Installer (recommended):** ``Captail-$Version-Setup-win-x64.exe`` includes Captail, .NET, libobs, FFmpeg, and an uninstaller.")
$lines.Add("- **Portable:** extract the entire ``Captail-$Version-Portable-win-x64.zip`` before launching ``Captail.exe``.")
$lines.Add("")
$lines.Add("## Compatibility and feedback")
$lines.Add("")
$lines.Add("Captail is tested on NVIDIA GeForce RTX 40 and RTX 50 series. Older NVIDIA, AMD, and Intel hardware needs broader public testing. Report problems through [GitHub Issues](https://github.com/$Repository/issues).")
$lines.Add("")
$lines.Add("Release binaries are not Authenticode-signed yet. Windows may show an unknown-publisher or SmartScreen warning. Use ``SHA256SUMS.txt`` and GitHub build provenance to verify the download.")

if ($PreviousTag) {
$lines.Add("")
$lines.Add("**Full changelog:** https://github.com/$Repository/compare/$PreviousTag...v$Version")
}

$outputFullPath = [IO.Path]::GetFullPath($OutputPath)
$outputDirectory = [IO.Path]::GetDirectoryName($outputFullPath)
if ($outputDirectory) {
[IO.Directory]::CreateDirectory($outputDirectory) | Out-Null
}

$notes = ($lines -join [Environment]::NewLine).TrimEnd() + [Environment]::NewLine
[IO.File]::WriteAllText(
$outputFullPath,
$notes,
[Text.UTF8Encoding]::new($false))

Write-Host "Release notes written to $outputFullPath"
Loading