From 091c56c1204da7bb9de811ec94a8f1fcf618badf Mon Sep 17 00:00:00 2001 From: Chrison Simtian Date: Sun, 23 Aug 2026 00:36:23 +1200 Subject: [PATCH] Rename the rolling channel from preview to nightly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub's immutable releases were briefly enabled here, and an immutable release reserves its tag permanently: deleting the release and the tag does not free the name. Recreating it fails with "creations being restricted", so the channel has been unable to publish since 16 August and `preview` is unusable in this repo forever. The rolling design is what conflicts โ€” one tag, force-moved on every push, is exactly what immutability forbids. Both the workflow and the CI docs now say so, so the next person reaches for per-commit tags rather than a third name. Also drops a stale pointer to InstallVsix, which no longer exists. Co-Authored-By: Claude Opus 5 (1M context) --- .github/ISSUE_TEMPLATE/config.yml | 4 +- .../workflows/{preview.yml => nightly.yml} | 48 +++++++++++-------- .github/workflows/publish.yml | 2 +- AGENTS.md | 2 +- docs/branching-and-release.md | 2 +- docs/ci.md | 15 +++--- docs/releasing.md | 14 +++--- 7 files changed, 48 insertions(+), 39 deletions(-) rename .github/workflows/{preview.yml => nightly.yml} (78%) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 47b2d9f..768ee60 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -9,6 +9,6 @@ contact_links: - name: ๐Ÿ“š Contributing & release docs url: https://github.com/Fallout-build/Fallout.Extensions.VSCode/blob/develop/CONTRIBUTING.md about: Branching, PR labels, and how this extension is built and released. - - name: ๐Ÿงช Preview build - url: https://github.com/Fallout-build/Fallout.Extensions.VSCode/releases/tag/preview + - name: ๐Ÿงช Nightly build + url: https://github.com/Fallout-build/Fallout.Extensions.VSCode/releases/tag/nightly about: Every push to develop publishes a rolling pre-release .vsix. Worth checking your issue isn't already fixed there. diff --git a/.github/workflows/preview.yml b/.github/workflows/nightly.yml similarity index 78% rename from .github/workflows/preview.yml rename to .github/workflows/nightly.yml index d6b8a3a..4966117 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/nightly.yml @@ -1,38 +1,44 @@ -# Hand-written (not auto-generated). The "preview" channel โ€” per-commit builds of develop. +# Hand-written (not auto-generated). The "nightly" channel โ€” per-commit builds of develop. # # Counterpart to the framework repo's publish-packages-preview.yml, which pushes a # -preview prerelease to GitHub Packages on every commit to main. The extension can't # do the same thing: GitHub Packages does not speak the VS Code gallery protocol, and -# neither marketplace accepts a semver prerelease version. So the preview channel here +# neither marketplace accepts a semver prerelease version. So the nightly channel here # is a ROLLING GitHub pre-release whose asset is replaced on every push. # # Why a rolling release rather than workflow artifacts: # - the download URL is stable, so installing is one command with no run-hunting: # -# gh release download preview -R Fallout-build/Fallout.Extensions.VSCode -p '*.vsix' --clobber +# gh release download nightly -R Fallout-build/Fallout.Extensions.VSCode -p '*.vsix' --clobber # code --install-extension fallout.vsix # -# or, from a clone: dotnet fallout InstallVsix # - workflow artifacts expire and need the run ID to fetch. # -# The tag is `preview`, deliberately NOT matching `v*`. Two consequences, both wanted: +# The tag is `nightly`, deliberately NOT matching `v*`. Two consequences, both wanted: # publish.yml (which triggers on v* only) does not fire, and the v* tag-protection # ruleset does not apply to a tag this workflow force-moves on every push. # +# It was `preview` until GitHub's immutable releases were briefly enabled on this repo. +# An immutable release reserves its tag permanently: deleting the release and the tag +# does not free the name, and recreating it fails with "creations being restricted". +# `preview` is therefore unusable here forever. Immutability and a force-moved tag are +# fundamentally incompatible โ€” if it is ever re-enabled, this channel needs per-commit +# tags instead of a rolling one, not another rename. +# # The .vsix is marked as a marketplace pre-release, so if it is ever sideloaded next to # a stable build VS Code shows it as pre-release rather than silently as a release. # # See docs/ci.md for how this fits with the other workflows. # # NOTE: this publishes NOTHING to any marketplace. It is the GitHub pre-stage only. -name: preview +name: nightly on: push: branches: # develop is the integration trunk under GitFlow, so it is what "latest" means. # main only ever receives release and hotfix merges, and those are tagged, so a - # preview build of main would duplicate a release build of the same commit. + # nightly build of main would duplicate a release build of the same commit. - develop paths-ignore: - '**/*.md' @@ -44,18 +50,18 @@ permissions: concurrency: # Never cancel in progress: a cancelled run could leave the rolling release holding a # half-uploaded asset. Queue instead, so the newest push wins by finishing last. - group: preview + group: nightly cancel-in-progress: false jobs: - preview: - name: preview + nightly: + name: nightly runs-on: ubuntu-latest permissions: contents: write environment: name: github-releases - url: https://github.com/Fallout-build/Fallout.Extensions.VSCode/releases/tag/preview + url: https://github.com/Fallout-build/Fallout.Extensions.VSCode/releases/tag/nightly steps: - uses: actions/checkout@v7 with: @@ -105,7 +111,7 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "Packaged version: $VERSION" - - name: 'Update the rolling preview release' + - name: 'Update the rolling nightly release' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} VERSION: ${{ steps.version.outputs.version }} @@ -113,7 +119,7 @@ jobs: set -euo pipefail NOTES=$(cat < /dev/null 2>&1; then - gh release edit preview --target "$GITHUB_SHA" --notes "$NOTES" --prerelease - gh release upload preview fallout.vsix --clobber + if gh release view nightly > /dev/null 2>&1; then + gh release edit nightly --target "$GITHUB_SHA" --notes "$NOTES" --prerelease + gh release upload nightly fallout.vsix --clobber else - gh release create preview \ - --title 'Preview (rolling)' \ + gh release create nightly \ + --title 'Nightly (rolling)' \ --target "$GITHUB_SHA" \ --notes "$NOTES" \ --prerelease \ diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 861586f..9d35e93 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -70,7 +70,7 @@ jobs: set -euo pipefail # Releases come from main (current line) or a support/vX.Y line (older Fallout # line still being served). NOT develop: under GitFlow the trunk is never - # tagged for release โ€” it ships through the preview channel instead. + # tagged for release โ€” it ships through the nightly channel instead. REACHABLE=$(git branch -r --contains "${{ github.sha }}" \ | grep -E 'origin/(main|support/v[0-9]+\.[0-9]+)$' || true) if [ -z "$REACHABLE" ]; then diff --git a/AGENTS.md b/AGENTS.md index ecc0981..1de1f57 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,7 +53,7 @@ Compilation is delegated to the project's own npm scripts rather than reimplemen ## Critical rules (read this every session) -1. **`.github/workflows/build.yml` is generated โ€” never hand-edit it.** It comes from the `[GitHubActions]` attribute in [`build/Build.CI.GitHubActions.cs`](build/Build.CI.GitHubActions.cs); edit the attribute and run `./build.sh` to regenerate. The file carries an `` header saying so. `publish.yml` and `preview.yml` are hand-written on purpose ([docs/ci.md](docs/ci.md#publishyml)). +1. **`.github/workflows/build.yml` is generated โ€” never hand-edit it.** It comes from the `[GitHubActions]` attribute in [`build/Build.CI.GitHubActions.cs`](build/Build.CI.GitHubActions.cs); edit the attribute and run `./build.sh` to regenerate. The file carries an `` header saying so. `publish.yml` and `nightly.yml` are hand-written on purpose ([docs/ci.md](docs/ci.md#publishyml)). 2. **`build.yml` and `build-skip.yml` must stay exact complements.** `build.yml` excludes `**/*.md`; `build-skip.yml` fires on exactly that path set, does nothing, and reports success under the same **job** name `ubuntu-latest` โ€” which *is* the required status-check context. A gap between the two path sets leaves a PR blocked forever on a check that never arrives. This is why the exclude is one flat pattern with no negations or carve-outs. Keep the job name, path sets, and branch lists in lockstep across both files. 3. **`version.json` and the pinned `Fallout.Common` move together.** `Build.AssertFrameworkLineMatches` fails the build if the declared line (`10.4`) drifts from the referenced framework version in `build/_build.csproj` *and* `plugins/Fallout.Vsce/Fallout.Vsce.csproj`. Bumping one and forgetting the other would ship a version that lies about what it targets. Never lower `versionHeightOffset` โ€” it keeps marketplace versions monotonic across `version.json` changes. 4. **Marketplace versions are three integers, no prerelease.** `vsce` rejects `10.4.30-rc.1` outright ("The VS Marketplace doesn't support prerelease versions"). A release candidate is a plain triple carrying a pre-release *bit* in the VSIX manifest (`Microsoft.VisualStudio.Code.PreRelease`), set at **package** time; `-rc.N` lives only on the git tag and GitHub release. **A version is pre-release or stable, never both** โ€” publishing `10.4.30` as a pre-release burns that number, so RCs stop at GitHub. `MarketplaceVersion` normalises all of this. diff --git a/docs/branching-and-release.md b/docs/branching-and-release.md index 8623255..899d540 100644 --- a/docs/branching-and-release.md +++ b/docs/branching-and-release.md @@ -8,7 +8,7 @@ How this repository branches, ships, and maintains older lines. The model is **G | Branch | Purpose | Lifetime | Tagged? | |---|---|---|---| -| `develop` | **Integration trunk. Default branch.** All finished work lands here first. Every push builds the [preview channel](releasing.md#the-preview-channel). | Permanent | No | +| `develop` | **Integration trunk. Default branch.** All finished work lands here first. Every push builds the [nightly channel](releasing.md#the-nightly-channel). | Permanent | No | | `main` | **Production.** Only receives merges from `release/*` and `hotfix/*`, and every one of those is tagged. Never committed to directly. | Permanent | **Yes** | | `release/*` | **Stabilisation window** for a release being prepared. Cut from `develop`; takes only fixes and release prep. Merges to `main` *and back to* `develop`, then deleted. | Short-lived | No (the merge into `main` is) | | `hotfix/*` | **Urgent production fix.** Cut from `main`. Merges to `main` *and* `develop`, then deleted. | Short-lived | No (the merge into `main` is) | diff --git a/docs/ci.md b/docs/ci.md index d584fb3..d7df871 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -10,7 +10,7 @@ The governing principle: **the build is defined in C#, not in YAML.** Every work |---|---|---|---| | `build.yml` | PR to `develop`, `main`, `support/*` | `PackVsix` โ€” the required check | **Yes**, from `[GitHubActions]` | | `build-skip.yml` | PR touching only `**/*.md` | Nothing; reports the same check | No | -| `preview.yml` | push to `develop` | Packs, publishes the rolling `preview` release | No | +| `nightly.yml` | push to `develop` | Packs, publishes the rolling `nightly` release | No | | `publish.yml` | `v*` tag push, or dispatch | Packs, releases, optionally promotes to marketplaces | No | ```mermaid @@ -21,8 +21,8 @@ flowchart LR B --> C(["ubuntu-latest โœ“"]) S --> C - D["Push to develop"] --> P["preview.yml"] - P --> PR2["rolling 'preview'
pre-release"] + D["Push to develop"] --> P["nightly.yml"] + P --> PR2["rolling 'nightly'
pre-release"] T["Tag v*"] --> V["publish.yml"] V --> R["GitHub release"] @@ -52,14 +52,15 @@ This is why `OnPullRequestExcludePaths` is a single `**/*.md` pattern. An earlie A PR touching both a `.md` and a source file runs **both** workflows. Both report `ubuntu-latest`, both pass. That's fine. -## preview.yml +## nightly.yml -Every push to `develop` packs a `.vsix`, uploads it as a per-run artifact, and replaces the asset on a rolling `preview` GitHub pre-release. Details and rationale in [releasing.md](releasing.md#the-preview-channel). +Every push to `develop` packs a `.vsix`, uploads it as a per-run artifact, and replaces the asset on a rolling `nightly` GitHub pre-release. Details and rationale in [releasing.md](releasing.md#the-nightly-channel). Two deliberate choices worth knowing when reading it: - **Concurrency queues, never cancels.** A cancelled run could leave the release holding a half-uploaded asset. -- **The tag is `preview`, which does not match `v*`.** So it neither triggers `publish.yml` nor falls under the `v*` tag-protection ruleset โ€” necessary, because the workflow force-moves that tag on every push. +- **The tag is `nightly`, which does not match `v*`.** So it neither triggers `publish.yml` nor falls under the `v*` tag-protection ruleset โ€” necessary, because the workflow force-moves that tag on every push. +- **Never enable immutable releases on this repo.** An immutable release reserves its tag permanently, which a force-moved tag cannot survive; it burned the original `preview` name for good. If immutability is ever required, this channel has to move to per-commit tags. ## publish.yml @@ -84,7 +85,7 @@ flowchart TD style OV fill:#7f4f24,color:#fff ``` -**`validate-ref`** confirms the tag is reachable from `main` or a `support/vX.Y` branch. Tags on `develop` are rejected: under GitFlow the trunk is never tagged for release โ€” it ships through the preview channel instead. +**`validate-ref`** confirms the tag is reachable from `main` or a `support/vX.Y` branch. Tags on `develop` are rejected: under GitFlow the trunk is never tagged for release โ€” it ships through the nightly channel instead. It runs only on tag pushes. On `workflow_dispatch` it's skipped by design, which is why every downstream job is guarded with `always() && needs..result == 'success'` rather than a bare dependency โ€” a skipped job otherwise propagates through the graph and silently skips everything after it *while the run still reports success*. diff --git a/docs/releasing.md b/docs/releasing.md index 60e2571..ba8143e 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -24,13 +24,13 @@ So an RC is an ordinary triple carrying a pre-release bit in the VSIX manifest ( **A version is pre-release or stable, never both.** Publishing `10.4.30` as a marketplace pre-release burns that number, forcing GA to `10.4.31`. Release candidates therefore stop at GitHub. -That argument does *not* apply to the [preview channel](#the-preview-channel): the patch is a git height, so every build already has a unique number and stable is always a later height. Nothing gets consumed that a stable release wants. +That argument does *not* apply to the [nightly channel](#the-nightly-channel): the patch is a git height, so every build already has a unique number and stable is always a later height. Nothing gets consumed that a stable release wants. ## Channels ```mermaid flowchart LR - DEV["develop"] -->|every push| PREV["preview
rolling pre-release"] + DEV["develop"] -->|every push| PREV["nightly
rolling pre-release"] MAIN["main / support/*"] -->|"v* tag"| GH["github-releases"] GH -.->|"opt-in flag
+ approval"| VSM["vs-marketplace"] GH -.->|"opt-in flag
+ approval"| OVSX["open-vsx"] @@ -43,21 +43,23 @@ flowchart LR | Channel | Trigger | Gating | |---|---|---| -| `preview` (rolling) | every push to `develop` | none | +| `nightly` (rolling) | every push to `develop` | none | | `github-releases` | any `v*` tag | none | | `vs-marketplace` | dispatch opt-in flag | flag + approval | | `open-vsx` | dispatch opt-in flag | flag + approval | **A tag push never reaches a marketplace.** Promotion is deliberate: set the flag, then approve the environment โ€” two independent layers, matching how Fallout gates nuget.org. -## The preview channel +## The nightly channel -Every push to `develop` builds a `.vsix`, uploads it as a per-run workflow artifact, and replaces the asset on a rolling `preview` GitHub pre-release. +Every push to `develop` builds a `.vsix`, uploads it as a per-run workflow artifact, and replaces the asset on a rolling `nightly` GitHub pre-release. + +> Named `preview` until GitHub's immutable releases were briefly enabled here. An immutable release reserves its tag **permanently** โ€” deleting the release and the tag does not free the name โ€” so `preview` is unusable in this repo forever. Keep immutable releases off: a rolling tag and immutability cannot coexist, and the next name would burn the same way. Both, deliberately: the release asset has a **stable URL** and is what you install from, but the next push replaces it โ€” so the per-run artifact is the fixed record of what a given commit produced. ```bash -gh release download preview -R Fallout-build/Fallout.Extensions.VSCode -p '*.vsix' --clobber +gh release download nightly -R Fallout-build/Fallout.Extensions.VSCode -p '*.vsix' --clobber code --install-extension fallout.vsix --force ```