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
31 changes: 25 additions & 6 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -943,11 +943,15 @@ jobs:
retention-days: 30

# ---------------------------------------------------------------------------
# Release: only runs on a v*.*.* tag push. Pulls both matrix artifacts
# down from the `build` job and attaches them to a GitHub Release.
# Release: only runs on a v*.*.* tag push. That tag is created by
# release-please (see .github/workflows/release-please.yml) when its
# release PR is merged — release-please also creates the GitHub Release
# with the generated changelog as the body. This job pulls both matrix
# artifacts down from the `build` job and ATTACHES them to that existing
# Release (it does not create one — see the attach step below).
# ---------------------------------------------------------------------------
release:
name: Create GitHub Release
name: Attach assets to release
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
Expand Down Expand Up @@ -978,14 +982,29 @@ jobs:
done
ls -la ../release/

- name: Create Release
# release-please (.github/workflows/release-please.yml) already created
# this tag's GitHub Release with the auto-generated changelog as the
# body. This step does NOT create a release — softprops finds the
# existing one (matched by the tag) and (a) uploads the built + signed
# assets and (b) APPENDS the static install instructions below the
# changelog. `append_body: true` is what preserves release-please's
# changelog instead of overwriting it; we deliberately drop
# `generate_release_notes` and `name:` so we don't fight release-please
# for ownership of those fields.
#
# Caveat: append_body is NOT idempotent — it re-appends the install
# block every time this job's attach step runs again for the same tag
# (e.g. the Actions "Re-run jobs" button on an already-green release).
# A failed signing/build re-run never reaches this step, so that common
# path is safe; if a duplicate does land, trim it from the release body
# by hand.
- name: Attach signed assets to release
uses: softprops/action-gh-release@v2
with:
files: release/*
generate_release_notes: true
append_body: true
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
name: ${{ github.ref_name }}
body: |
## ${{ env.LAYER_NAME }} ${{ github.ref_name }}

Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: release-please

# Conventional-Commits release automation.
#
# On every push to main, release-please opens (and keeps updating) a single
# "release PR" that bumps the version in version.txt and regenerates
# CHANGELOG.md from the feat:/fix: commits landed since the last release.
# Merging that PR is the release trigger: release-please creates the
# vX.Y.Z git tag and a GitHub Release whose body is the generated changelog.
#
# That tag is what starts build-and-release.yml (build + Certum signing +
# asset upload). Its `release` job then attaches the signed DLL/installer to
# the very Release this action created — see the "Attach signed assets to
# release" step over there.
#
# WHY THE CUSTOM TOKEN (secrets.RELEASE_PLEASE_TOKEN):
# A tag/Release created with the built-in GITHUB_TOKEN does NOT trigger
# other workflows — GitHub suppresses those events to prevent infinite
# loops. If we used GITHUB_TOKEN here, build-and-release.yml would never
# fire on the new tag and every Release would ship with an empty asset
# list. The secret must be a PAT (or GitHub App token) with, on this repo,
# Contents: read/write + Pull requests: read/write. Setup steps are in
# docs/DEVELOPMENT.md -> "Releases" -> "Required secret: RELEASE_PLEASE_TOKEN".
on:
push:
branches: [main]

# Governs the built-in GITHUB_TOKEN. release-please itself authenticates
# with the PAT passed as `token:` below, but the action still touches the
# default token for some calls, so keep these scopes granted.
permissions:
contents: write
pull-requests: write
issues: write

# Serialise release-please runs so two quick pushes to main don't race on
# updating the same release PR. Don't cancel an in-flight run — letting it
# finish keeps the release PR consistent.
concurrency:
group: release-please-${{ github.ref }}
cancel-in-progress: false

jobs:
release-please:
name: Maintain release PR / cut release
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "1.0.0"
}
82 changes: 67 additions & 15 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,32 @@ Suite against the layer on your target runtime — see

## Releases

The GitHub Actions workflow
([`build-and-release.yml`](../.github/workflows/build-and-release.yml))
builds `Release` and `Debug` x64 on every push to `main` (as a sanity
check), every PR, and every `v*.*.*` tag. On a tag push it
additionally creates a GitHub Release and attaches:
Releases are automated with
[release-please](https://github.com/googleapis/release-please)
([`release-please.yml`](../.github/workflows/release-please.yml)),
driven by [Conventional Commits](https://www.conventionalcommits.org/).
You never push a release tag by hand.

**The flow:**

1. Land Conventional-Commit commits on `main` — `feat:` → minor bump,
`fix:` → patch, `feat!:` / `BREAKING CHANGE:` → major. Commits
whose type isn't recognised (chore, docs, ci, …) don't appear in
the changelog and don't move the version.
2. release-please keeps an open **"chore: release X.Y.Z" PR** that
bumps [`version.txt`](../version.txt) and regenerates `CHANGELOG.md`
(created by the first release PR) from those commits. It rewrites
itself on every push to `main` — leave it alone until you're ready
to ship.
3. **Merging that PR is the release action.** release-please then
creates the `vX.Y.Z` tag and a GitHub Release whose body is the
generated changelog.
4. That tag triggers
[`build-and-release.yml`](../.github/workflows/build-and-release.yml),
which builds + signs `Release`/`Debug` x64 and **attaches** the
assets to the Release release-please just created — appending the
install instructions below the changelog rather than overwriting
it:

- `XR_APILAYER_MLEDOUR_xr_telemetry-<version>-x64-Setup.exe` —
Inno Setup installer (recommended for end users)
Expand All @@ -460,18 +481,43 @@ additionally creates a GitHub Release and attaches:
- `XR_APILAYER_MLEDOUR_xr_telemetry-Debug-x64.zip` — debug build
with full symbols, for troubleshooting

To publish a new release:
`build-and-release.yml` still also builds `Release`/`Debug` on every
push to `main` and every PR as a verification gate (unsigned, no
Release) — that part is unchanged.

```bash
git tag v0.1.0
git push origin v0.1.0
```

The tag is derived into the DLL's `VERSIONINFO` resource at build
The version is derived into the DLL's `VERSIONINFO` resource at build
time via
[`scripts/Generate-VersionRc.ps1`](../scripts/Generate-VersionRc.ps1),
and into the installer's filename and `AppVersion` via the
`/DMyAppVersion` flag passed to ISCC.
[`scripts/Generate-VersionRc.ps1`](../scripts/Generate-VersionRc.ps1)
(from the `v*.*.*` tag, falling back to `git describe`), and into the
installer's filename and `AppVersion` via the `/DMyAppVersion` flag
passed to ISCC.

> **Bootstrapping:**
> [`.release-please-manifest.json`](../.release-please-manifest.json)
> is seeded at `1.0.0` to match the existing `v1.0.0` tag, so the
> first release PR bumps from there using the commits landed since.

### Required secret: `RELEASE_PLEASE_TOKEN`

release-please must tag using a token **other than** the built-in
`GITHUB_TOKEN`. GitHub deliberately does not let events created with
`GITHUB_TOKEN` trigger further workflows (an anti-recursion measure),
so a tag pushed with it would never start `build-and-release.yml` and
the Release would ship with **no assets**. Provide a token as the
`RELEASE_PLEASE_TOKEN` repository secret (Settings → Secrets and
variables → Actions → New repository secret):

| Option | What to grant |
|--------|---------------|
| **Fine-grained PAT** (recommended) | This repo only; repository permissions **Contents: Read and write** + **Pull requests: Read and write** |
| **Classic PAT** | `repo` scope |
| **GitHub App token** | `contents: write` + `pull_requests: write` — no expiry, more setup |

Because release-please authenticates with this PAT, the "Allow GitHub
Actions to create and approve pull requests" repo/org toggle is **not**
required (that setting only gates the default `GITHUB_TOKEN`). If the
secret is missing or under-scoped, the release-please job fails fast
with a 403 — it never silently produces an asset-less Release.

## Code signing

Expand Down Expand Up @@ -629,6 +675,12 @@ echoed by `Sign-Artifact.ps1` and `Get-CertumTotp.ps1`, and the
PowerShell scripts pass them as process arguments rather than through
`cmd /c` so they don't leak into the shell-history transcript.

> These three are **signing** secrets and are all optional (each
> signing step skips cleanly when its secret is unset, yielding
> unsigned artifacts). Release **automation** needs a separate secret,
> [`RELEASE_PLEASE_TOKEN`](#required-secret-release_please_token),
> documented under [Releases](#releases) above.

Certum SimplySign uses 2FA where the **TOTP is the second factor** —
there is no separate static password to set, so we don't need a
`CERTUM_PASSWORD` secret. Username + freshly-generated TOTP is the
Expand Down
8 changes: 8 additions & 0 deletions release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"release-type": "simple",
"include-component-in-tag": false,
"packages": {
".": {}
}
}
1 change: 1 addition & 0 deletions version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
Loading