Repository navigation
chore: cut specification releases with release-please - #440
Conversation
The specification's vX.Y.Z tags are created by hand today. That is a step easy to postpone -- v0.9.0 went out in July and the four commits since it are unreleased -- and a step where the changelog is assembled by whoever remembers to. release-please proposes the version and the notes as a pull request instead, and tags when it is merged. Nothing about the tag shape changes. include-component-in-tag is false, so releases stay vX.Y.Z rather than becoming spec/vX.Y.Z, and the manifest starts at 0.9.0 so numbering continues from the current release instead of restarting. bump-minor-pre-major keeps the pre-1.0 convention the specification already follows, where a breaking change bumps the minor. release-type is simple because the root package.json is private and carries no version of its own; simple tracks the version in version.txt. One consequence worth naming in review: release notes become generated from conventional commits, where v0.9.0's were written by hand. Anything that needs saying beyond the commit subjects -- the breaking-change callout at the top of v0.9.0, say -- now has to be added to the release pull request before it is merged. This is deliberately the whole of it: a single package, no tag separator and no component tagging, because there is nothing else in the repository to release yet. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
Three inputs in the workflow were written against the v3 action and are silently ignored by v5, which is worse than an error because the workflow still runs and appears to work: - command: manifest is not an input. v5 is manifest-mode whenever a config file is present, which it is. - default-branch was renamed target-branch. - signoff moved to the configuration file, as $.signoff. The last one matters here. This repository enforces DCO, so an ignored signoff means release-please's own commits arrive without a Signed-off-by line and its release pull request fails the DCO check -- the failure the option was added to prevent. It is now a key in release-please-config.json, where v5 reads it. Also adds issues: write, which the action's own recommended permissions block carries; release-please labels its pull requests, and labelling goes through the issues API. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (1)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review. 📝 WalkthroughWalkthroughAdds Release Please configuration for the repository root, sets its version to ChangesRelease automation
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Other Sequence Diagram(s)sequenceDiagram
participant GitHub
participant ReleasePleaseWorkflow as Release Please workflow
participant ReleasePleaseAction as Release Please action
GitHub->>ReleasePleaseWorkflow: Push to main
ReleasePleaseWorkflow->>ReleasePleaseAction: Invoke action with GitHub token and main target
Merge Risk: ⚪ Minimal · up to The release configuration has no confirmed merge-blocking defect. The repository’s required-check settings remain unverified. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The automation is limited to pushes to main and uses a repository token rather than a separate privileged credential. No concrete vulnerability was established, but repository write authority is newly delegated to an external action. Enforced merge approval and recovery from interrupted or concurrent releases remain unverified. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
a508a34 to
e1eb080
Compare
A second release-please package, so the assets added here are tagged specification/assets/provider-tck/vX.Y.Z. That is the shape `go get` needs: without a tag a Go consumer can only name a pseudo-version, which is what the four conformance implementations have had to do while this branch was unmerged. The specification package excludes this path, so an asset-only change no longer cuts a specification release, and separate-pull-requests keeps the two from sharing one release pull request. The general release-please setup is #440, which this stacks on; this commit adds only the part that describes the assets beside them. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
A second release-please package, so the assets added here are tagged specification/assets/provider-tck/vX.Y.Z. That is the shape `go get` needs: without a tag a Go consumer can only name a pseudo-version, which is what the four conformance implementations have had to do while this branch was unmerged. The specification package excludes this path, so an asset-only change no longer cuts a specification release, and separate-pull-requests keeps the two from sharing one release pull request. The general release-please setup is #440, which this stacks on; this commit adds only the part that describes the assets beside them. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Embedded artifacts are byte-identical, so the digest is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical, so PINNED_DIGEST is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
A second release-please package, so the assets added here are tagged specification/assets/provider-tck/vX.Y.Z. That is the shape `go get` needs: without a tag a Go consumer can only name a pseudo-version, which is what the four conformance implementations have had to do while this branch was unmerged. The specification package excludes this path, so an asset-only change no longer cuts a specification release, and separate-pull-requests keeps the two from sharing one release pull request. The general release-please setup is #440, which this stacks on; this commit adds only the part that describes the assets beside them. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
A second release-please package, so the assets added here are tagged specification/assets/provider-tck/vX.Y.Z. That is the shape `go get` needs: without a tag a Go consumer can only name a pseudo-version, which is what the four conformance implementations have had to do while this branch was unmerged. The specification package excludes this path, so an asset-only change no longer cuts a specification release, and separate-pull-requests keeps the two from sharing one release pull request. The general release-please setup is #440, which this stacks on; this commit adds only the part that describes the assets beside them. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Embedded artifacts are byte-identical, so the digest is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical, so PINNED_DIGEST is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
> **Part of [#417](#417 This PR is the **assets** — the files four conformance implementations execute. It stacks on [#440](#440), which configures the releases that give these assets a tag. The normative description of them, Appendix F, is [#439](#439), stacked on this. [#425](#425) adds the machine-readable report. > > This PR previously carried the appendix too. It was split so the assets can land while the prose is still being reviewed. ## What The artifacts a provider conformance suite runs against: | path | what it is | |---|---| | `assets/provider-tck/gherkin/` | six feature files — evaluation, errors, events, lifecycle, reason, metadata | | `assets/provider-tck/flags/canonical-flags.json` | the flag set every scenario assumes | | `assets/provider-tck/openapi/control-api.yaml` | the HTTP surface a backend under test must expose | | `assets/provider-tck/go.mod`, `embed.go` | a nested Go module exposing the artifacts as an `embed.FS` | | `release-please-config.json`, `.release-please-manifest.json` | registers the assets as a releasable component; the general setup is #440 | Marked **experimental**: the scenario set is a representative subset, and the capability vocabulary may still change. ## Why this is split out Four language implementations already run these files, and all four are currently pinned to an **unmerged branch tip**. Every rebase here invalidates them — it has happened three times in two weeks. Nothing about those pins becomes real until the assets are on `main` with a tag, so landing the executable half first is worth more than landing it together with prose that will take longer to review. Appendix F is the same work, reviewed on its own terms. ## Why a Go module is in here A Go module is distributed as a zip of the VCS tree, in which a git submodule is only a gitlink and its files are absent. The other three languages build from a working tree and keep using the submodule, but a Go suite would have to vendor a copy of every artifact and police it against drift. `embed.go` removes the copy: a consumer pins a revision, the checksum database makes it immutable, and the embedded bytes are the same bytes every other language reads out of the submodule. `go.mod` and `embed.go` are inert for every non-Go consumer. Precedent: `open-feature/flagd-schemas`. The release config tags the assets as their own component, `specification/assets/provider-tck/vX.Y.Z` — the shape `go get` needs. Without it a Go consumer can only name a pseudo-version. ## Releasing the assets The general release-please setup is [#440](#440), which this stacks on. What this PR adds is the part that describes *these* assets: a second package, so they are tagged `specification/assets/provider-tck/vX.Y.Z`. That tag shape is what `go get` needs. Without it a Go consumer can only name a pseudo-version, which is what the four conformance implementations have had to do while this branch was unmerged, and it has cost several rounds of re-pinning. The specification package sets `exclude-paths` for this directory, so an asset-only change no longer cuts a specification release, and `separate-pull-requests` keeps the two from sharing one release pull request. ## The capability vocabulary lives in the README, for now A scenario exercising an optional part of the contract carries a tag; a provider declares what it supports, and a scenario gated on an undeclared tag is reported **skipped, with the reason** — never as passed. A suite that quietly goes green on scenarios it did not run is worse than no suite at all. That rule and the tag table are in `assets/provider-tck/README.md` so the tags in the feature files are not left undefined while the appendix is in review. #439 moves them into the appendix and leaves a pointer behind, so they end up with one home rather than two that can disagree. Worth stating plainly: **withholding a tag is not an admission of a defect.** `@numeric-coercion` borrows its rule from flagd's coercion ADR, and `@string-typing` / `@fully-typed-values` sit on a question the specification does not answer at all — [#430](#430) and [#433](#433). ## Decisions worth reviewing - **`assets/provider-tck/` rather than beside the SDK Gherkin**, because `assets/gherkin/evaluation.feature` already exists and tests an SDK, not a provider. This answers #417's Q1 — the subdirectory is forced rather than chosen. - **`.gitattributes` normalises these to LF.** Four languages consume them byte for byte and copy them verbatim into published artifacts, so a Windows checkout must not package differently from a Linux one. - **`missing-flag` must not exist** in the flag set — its absence is what the `FLAG_NOT_FOUND` scenario tests. The other four load-bearing properties of the flag set are in the README; each one, if seeded wrong, turns a scenario green or red for the wrong reason in every language at once. - **No container restarts.** Outages are produced through the control API, because orchestrators reassign host ports on restart and every provider pointed at the old one then fails looking flaky. ## Implementations All four execute exactly these files, against flagd (both resolvers), OFREP and Flagsmith: | | suite | flagd | OFREP | Flagsmith | |---|---|---|---|---| | Java | [#1830](open-feature/java-sdk-contrib#1830) | [#1847](open-feature/java-sdk-contrib#1847) | [#1840](open-feature/java-sdk-contrib#1840) | [#1849](open-feature/java-sdk-contrib#1849) | | Go | [#940](open-feature/go-sdk-contrib#940) | [#941](open-feature/go-sdk-contrib#941) | [#942](open-feature/go-sdk-contrib#942) | [#959](open-feature/go-sdk-contrib#959) | | JavaScript | [#1606](open-feature/js-sdk-contrib#1606) | [#1608](open-feature/js-sdk-contrib#1608) | [#1612](open-feature/js-sdk-contrib#1612) | [#1623](open-feature/js-sdk-contrib#1623) | | Python | [#409](open-feature/python-sdk-contrib#409) | [#411](open-feature/python-sdk-contrib#411) | [#414](open-feature/python-sdk-contrib#414) | — | ## What running them has found - **flagd silently narrows a float flag to an integer**, Go and Java, both resolvers, no error code — [flagd#1996](open-feature/flagd#1996) - **flagd reported ready before flags were evaluable**, on 100% of starts — [flagd#2047](open-feature/flagd#2047), fixed in flagd v0.17.0 - **The Java SDK's `MultiProvider` swallows child provider events** — [java-sdk#1882](open-feature/java-sdk#1882) - **The Python flagd provider widens a boolean to a float** — [python-sdk-contrib#417](open-feature/python-sdk-contrib#417) - **The JavaScript Flagsmith provider stringifies unconditionally** where its other paths correctly report a mismatch — visible only because three languages ran identical scenarios against one backend - two specification gaps, raised rather than decided here: [#430](#430), [#433](#433) --------- Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Embedded artifacts are byte-identical, so the digest is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical, so PINNED_DIGEST is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Embedded artifacts are byte-identical, so the digest is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
open-feature/spec#440 landed the general release-please setup on main, so #423 was replayed onto it without those commits and its tip moved. Artifacts are byte-identical, so PINNED_DIGEST is unchanged. Signed-off-by: Simon Schrottner <simon.schrottner@flagsmith.com>
What
Sets up release-please to cut the specification's releases, replacing the manual tagging step.
Why
The
vX.Y.Ztags are created by hand. That is easy to postpone — v0.9.0 went out in July and the commits since it are unreleased — and it assembles the changelog from whoever's memory is handy. release-please proposes the version and the notes as a pull request, and tags once that pull request is merged.What does not change
v0.9.0v0.9.1,v0.10.0, …include-component-in-tag: falsekeeps the barevX.Y.Zshape rather thanspec/vX.Y.Z, and.release-please-manifest.jsonstarts at0.9.0so numbering continues rather than restarting.release-type: simplebecause the rootpackage.jsonisprivate: trueand carries no version of its own;simpletracks the version inversion.txt, which is why that file is added here.Scope: the specification package only
One package,
., taggedvX.Y.Zas it always has been.The conformance assets under
specification/assets/provider-tckneed their own tags too — a Go consumer cannot name a version without one — but that configuration belongs beside the assets, so it is added in #423 along with the files it describes. This PR stays the general setup and can merge on its own.What does change, and needs a decision
Release notes become generated from conventional commits. v0.9.0's notes were written by hand, including the
⚠️ This release contains breaking changescallout linking #280, #306 and #360. Anything beyond the commit subjects now has to be added to the release pull request before it is merged.If the TSC would rather keep the old shape,
changelog-sectionscan be tuned in a follow-up — the defaults are left here so the first release is easy to eyeball.What to expect on merge
release-please runs on push to
mainand should open a release pull request proposing v0.9.1; the non-chore commits since v0.9.0 are #416, #419, #429 and #408, allfix:ordocs:. Nothing is tagged until that pull request is merged, so the first run is reviewable before it has any effect.The action configuration is the shape v5 actually reads:
commandanddefault-branchare not v5 inputs,target-branchis, andsignoffis a configuration-file option rather than an action input — which matters because this repository enforces DCO on the bot's own commits.