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
4 changes: 2 additions & 2 deletions .agents/skills/elsa-release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ description: Release Elsa from elsa-core as one tag, one GitHub release and one
## What core publishes today (verify against `origin/main` before relying on it)

- `.github/workflows/packages.yml` runs on `release: published`, pushes to `main` and `release/*`, and `workflow_dispatch`. A release or push only tests, builds and uploads the `elsa-nuget-packages` artifact. It never publishes. Publication needs an approved `workflow_dispatch` with `publish_preview_feedz` (Feedz: a branch, or a `3.10.x` prerelease tag) or `publish_nuget` (nuget.org: a release-version tag, including stable `3.10.x`). Stable 3.10.x Feedz is owned only by `publish-consolidated-original-candidate.yml`.
- Stable `3.10.x` nuget.org publishing is blocked until re-pin ([#9016](https://github.com/elsa-workflows/elsa-core/issues/9016)). Both the `packages.yml` promote path and `publish-consolidated-original-candidate.yml` run `scripts/validate_packages_id_set.py` on the current pin (run/artifact `11412848210`, 225 packages) before any push, so that set cannot be published as 3.10.0. After #9016 re-pins a fresh candidate from the `release/3.10.0` tip, nuget.org promotion and the candidate Feedz publish can proceed. Neither workflow is part of the ordinary release-train helper.
- `studio-npm-pair.yml` only proves that the two Studio npm archives can be built and consumed locally. `packages.yml` `publish_npm` publishes `@elsa-workflows/elsa-studio-wasm` and `@elsa-workflows/elsa-studio-wasm-react` to Feedz from a 3.10.x prerelease tag. Stable Feedz publication waits for the 231-ID nuget.org promote guard. The npmjs.com upload is not in this job until trusted publishing is confirmed for `elsa-workflows/elsa-core`. Stable 3.10.x nuget.org publication is blocked until re-pin ([#9016](https://github.com/elsa-workflows/elsa-core/issues/9016)) (part of [#8725](https://github.com/elsa-workflows/elsa-core/issues/8725)).
- Both the `packages.yml` promote path and `publish-consolidated-original-candidate.yml` run `scripts/validate_packages_id_set.py` on the current pin (run `40347931480`, artifact `12664519771`, 231 packages from `release/3.10.0` @ `5cff67228e550b353b3483eb3b37dfdb73a41c74`) before any push. Neither workflow is part of the ordinary release-train helper.
- `studio-npm-pair.yml` only proves that the two Studio npm archives can be built and consumed locally. `packages.yml` `publish_npm` publishes `@elsa-workflows/elsa-studio-wasm` and `@elsa-workflows/elsa-studio-wasm-react` to Feedz from a 3.10.x prerelease tag. Stable Feedz publication waits for the 231-ID nuget.org promote guard. The npmjs.com upload is not in this job until trusted publishing is confirmed for `elsa-workflows/elsa-core`. Stable 3.10.x nuget.org publication uses the current 231-ID pin (part of [#8725](https://github.com/elsa-workflows/elsa-core/issues/8725)).
- The Apps container workflow lived in `elsa-apps` and core has no replacement yet. The container stage is blocked until it is re-homed in core.

## Interpret the request
Expand Down
22 changes: 9 additions & 13 deletions .agents/skills/elsa-release/references/runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Studio, Extensions and Apps are folded into `elsa-core`; a release is one `elsa-
What `elsa-core` actually does today (check `origin/main` before relying on it):

- `.github/workflows/packages.yml` builds and uploads packages on `release: published` and on pushes to `main` and `release/*`. Those events never publish. Publication is an approved `workflow_dispatch`: `publish_preview_feedz` (Feedz, from a branch or a `3.10.x` prerelease tag) or `publish_nuget` (nuget.org, from a release-version tag). Stable `3.10.x` Feedz is owned only by `publish-consolidated-original-candidate.yml`.
- Its `./build.sh Compile+Pack` packs Core only on branch pushes and non-`3.10.0` tags. A `3.10.0` tag `release` event (and a non-promote dispatch from that tag) packs the 231-ID set through `prepare_consolidated_release_candidate.py`. Stable `3.10.x` nuget.org publishing is blocked until re-pin ([#9016](https://github.com/elsa-workflows/elsa-core/issues/9016)). A `publish_nuget` dispatch on a stable `3.10.x` tag does not pack: it downloads the current pin (run/artifact `11412848210`), verifies each `.nupkg` sha256 against that candidate's seal, and runs `scripts/validate_packages_id_set.py` (231 IDs plus the three Studio ClientLib assets per package) before any push. The Oct 6 225-package set fails that guard. That pin's archive size and expiry (`2026-11-05T12:13:30Z`) come from `stable-original-envelope.json`; the replacement candidate's expiry is unknown until it is built. After the freeze, once the [3.10] picks and advisory fixes have landed, #9016 builds a fresh candidate from the `release/3.10.0` tip and re-pins it. `Elsa.SamplePackage` is not packable. The five `Elsa.Secrets.*` IDs and the four `Elsa.Studio.Host.*` IDs stay unpackable and `Elsa.Templates` is not in core. The whole-product 3.10.0 candidate is [prepared without publishing](#consolidated-3100-candidate-preparation-nonpublishing); `publish-consolidated-original-candidate.yml` is the only Feedz publisher for those stable 3.10.x bytes and runs the same 231-ID guard before its Feedz push (also blocked until re-pin (#9016)).
- Its `./build.sh Compile+Pack` packs Core only on branch pushes and non-`3.10.0` tags. A `3.10.0` tag `release` event (and a non-promote dispatch from that tag) packs the 231-ID set through `prepare_consolidated_release_candidate.py`. A `publish_nuget` dispatch on a stable `3.10.x` tag does not pack: it downloads the current pin (run `40347931480`, artifact `12664519771`, source `5cff67228e550b353b3483eb3b37dfdb73a41c74`), verifies each `.nupkg` sha256 against that candidate's seal, and runs `scripts/validate_packages_id_set.py` (231 IDs plus the three Studio ClientLib assets per package) before any push. That pin's archive size and expiry (`2026-11-25T16:05:50Z`) come from `stable-original-envelope.json`. `Elsa.SamplePackage` is not packable. The five `Elsa.Secrets.*` IDs and the four `Elsa.Studio.Host.*` IDs stay unpackable and `Elsa.Templates` is not in core. The whole-product 3.10.0 candidate is [prepared without publishing](#consolidated-3100-candidate-preparation-nonpublishing); `publish-consolidated-original-candidate.yml` is the only Feedz publisher for those stable 3.10.x bytes and runs the same 231-ID guard before its Feedz push.
- `studio-npm-pair.yml` is a local proof of the two Studio npm archives. `packages.yml` `publish_npm` publishes `@elsa-workflows/elsa-studio-wasm` and `@elsa-workflows/elsa-studio-wasm-react` to Feedz from a 3.10.x prerelease tag. The npmjs.com upload is not in this job until trusted publishing is confirmed for `elsa-workflows/elsa-core`. Stable `3.10.x` stays fail-closed until the 231-ID nuget.org promote guard can pass. The pair builder accepts 3.8–3.10 versions only.
- Core has no container-image publishing workflow. The Apps workflow it used lived in `elsa-apps`.

Expand All @@ -30,7 +30,7 @@ Check:
- All configured package workflow `base_version` values match the new release line before branch CI. Templates stable workflow policy is checked separately: its `BASE_VERSION` and embedded Core/Studio PackageReferences must match the requested stable version, while a prerelease source must be selected explicitly or from its release branch. Version tags drive named release artifacts, but the branch preview version must also be correct. Make routine preparation changes on the intended release branch when needed.
- Before a Templates RC/preview run, inspect its release workflow's tag ancestry guard. It must accept the selected `origin/release/<base-version>` or explicit prerelease source; if it only accepts `origin/main`, resolve that workflow/source mismatch in the Templates repository before publishing. Never claim a release-line source is runnable while the workflow silently rejects its tag.
- The workflow subscribes once to `release: types: [published]`. GitHub `published` covers both stable and prereleases. Use `release.prerelease` or parsed package versions for distinctions, never `event.action == published` as a stable-only test. [GitHub reference](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#release).
- Named stable, RC and preview releases use the approved publication workflows, never the release event itself: nuget.org for release-version tags (stable `3.10.x` is blocked until re-pin (#9016)), Feedz for branches and `3.10.x` prerelease tags through `packages.yml`, and stable `3.10.x` Feedz publication through `publish-consolidated-original-candidate.yml` (also blocked until re-pin (#9016)). Automated branch previews are separate, Feedz-only builds. Studio npm `next`/`latest` publication does not exist in core yet (pending #8725); do not expect it. If the source workflow disagrees with this policy, resolve the mismatch before release; do not weaken verification to match missing output.
- Named stable, RC and preview releases use the approved publication workflows, never the release event itself: nuget.org for release-version tags (stable `3.10.x` uses the pinned 231-ID candidate), Feedz for branches and `3.10.x` prerelease tags through `packages.yml`, and stable `3.10.x` Feedz publication through `publish-consolidated-original-candidate.yml`. Automated branch previews are separate, Feedz-only builds. Studio npm `next`/`latest` publication does not exist in core yet (pending #8725); do not expect it. If the source workflow disagrees with this policy, resolve the mismatch before release; do not weaken verification to match missing output.
- Identify advisories and build/test prerequisites early. Assess actual usage and document disposition; a known warning from a prior release is evidence, not permanent acceptance. Keep unrelated upgrades out of the release. New material unresolved risks or failures require an explicit resolution before irreversible publication.

Before creating a named release, perform a publishing credential preflight for
Expand Down Expand Up @@ -380,7 +380,7 @@ python3 scripts/integration-program/prepare_consolidated_release_candidate.py \
The canonical proof evaluator derives every package/exclusion from current
Elsa.sln properties. It compares IDs, project paths and exclusion reasons with
`consolidated-candidate-inventory-baseline.json`, derived from the accepted proof
inventory. The 225 package/symbol pairs and 124 excluded projects (123 IDs) are
inventory. The 231 package/symbol pairs and 135 excluded projects (134 IDs) are
baseline sanity evidence, never an allowlist. A difference emits
`inventory-diff.json` and stops before building. Review and commit any justified
baseline update; do not silently shrink it. The five retired Extensions Secrets
Expand Down Expand Up @@ -429,16 +429,12 @@ publication. The #8629 proof-version persisted matrix cannot certify different
stable candidate bytes: applicable persisted compatibility checks must bind to
the admitted candidate production bytes before that candidate is published.
`publish-consolidated-original-candidate.yml` is the only Feedz publisher for
those stable 3.10.x bytes. Stable 3.10.x nuget.org publishing is blocked until
re-pin ([#9016](https://github.com/elsa-workflows/elsa-core/issues/9016)). A
`packages.yml` nuget.org dispatch on a stable 3.10.x tag downloads the current
pin (run/artifact `11412848210`), verifies each `.nupkg` sha256 against the
candidate seal, and runs the same 231-ID and Studio content guards that the
candidate Feedz publisher runs before its push. The current 225-package set
fails that guard, so neither path can publish 3.10.0 until #9016 re-pins a
fresh candidate from the `release/3.10.0` tip. The promote path does not
restore, build, or pack. `3.10.1` and later stay blocked until a new pin
exists.
those stable 3.10.x bytes. A `packages.yml` nuget.org dispatch on a stable
3.10.x tag downloads the current pin (run `40347931480`, artifact
`12664519771`), verifies each `.nupkg` sha256 against the candidate seal, and
runs the same 231-ID and Studio content guards that the candidate Feedz
publisher runs before its push. The promote path does not restore, build, or
pack. `3.10.1` and later stay blocked until a new pin exists.

This task implements no publisher handoff. Ordinary approved Core publication
selection remains a `packages.yml` dispatch: branch previews and 3.10.x
Expand Down
32 changes: 16 additions & 16 deletions .github/workflows/consolidated-package-recovery-preflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@ jobs:
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/recovery-input"
gh api repos/elsa-workflows/elsa-core/actions/artifacts/11412848210 > "$RUNNER_TEMP/recovery-input/artifact.json"
gh api repos/elsa-workflows/elsa-core/actions/runs/37456860080/attempts/1 > "$RUNNER_TEMP/recovery-input/producer-run.json"
jq -e '.id == 37456860080 and .run_attempt == 1 and
.head_sha == "ba5b348aa2414fdf7c19d9d8806e87b7c91a4205" and .conclusion == "success" and
gh api repos/elsa-workflows/elsa-core/actions/artifacts/12664519771 > "$RUNNER_TEMP/recovery-input/artifact.json"
gh api repos/elsa-workflows/elsa-core/actions/runs/40347931480/attempts/1 > "$RUNNER_TEMP/recovery-input/producer-run.json"
jq -e '.id == 40347931480 and .run_attempt == 1 and
.head_sha == "5cff67228e550b353b3483eb3b37dfdb73a41c74" and .conclusion == "success" and
(.event == "push" or .event == "workflow_dispatch") and
.path == ".github/workflows/prepare-consolidated-release-candidate.yml"' "$RUNNER_TEMP/recovery-input/producer-run.json" > /dev/null
jq -e '.id == 11412848210 and
.name == "consolidated-candidate-ba5b348aa2414fdf7c19d9d8806e87b7c91a4205-37456860080-1" and
.expired == false and .expires_at == "2026-11-05T12:13:30Z" and
.digest == "sha256:ace85260c3389916fe3dcd7ee9cd5b766e4030dd6cee13c7f89285ada79c944f" and
.size_in_bytes == 92659861 and .workflow_run.id == 37456860080 and
.workflow_run.head_sha == "ba5b348aa2414fdf7c19d9d8806e87b7c91a4205"' "$RUNNER_TEMP/recovery-input/artifact.json" > /dev/null
test "$(date -u -d '2026-11-05T12:13:30Z' +%s)" -gt "$(date -u +%s)"
gh api repos/elsa-workflows/elsa-core/actions/artifacts/11412848210/zip > "$RUNNER_TEMP/recovery-input/candidate.zip"
test "$(stat -c %s "$RUNNER_TEMP/recovery-input/candidate.zip")" -eq 92659861
jq -e '.id == 12664519771 and
.name == "consolidated-candidate-5cff67228e550b353b3483eb3b37dfdb73a41c74-40347931480-1" and
.expired == false and .expires_at == "2026-11-25T16:05:50Z" and
.digest == "sha256:2dd253e1f2946ddcb2b8e75ef397596001757ddbcb0a91f717e9505bbf28b4f6" and
.size_in_bytes == 96096205 and .workflow_run.id == 40347931480 and
.workflow_run.head_sha == "5cff67228e550b353b3483eb3b37dfdb73a41c74"' "$RUNNER_TEMP/recovery-input/artifact.json" > /dev/null
test "$(date -u -d '2026-11-25T16:05:50Z' +%s)" -gt "$(date -u +%s)"
gh api repos/elsa-workflows/elsa-core/actions/artifacts/12664519771/zip > "$RUNNER_TEMP/recovery-input/candidate.zip"
test "$(stat -c %s "$RUNNER_TEMP/recovery-input/candidate.zip")" -eq 96096205
printf '%s %s\n' \
'ace85260c3389916fe3dcd7ee9cd5b766e4030dd6cee13c7f89285ada79c944f' \
'2dd253e1f2946ddcb2b8e75ef397596001757ddbcb0a91f717e9505bbf28b4f6' \
"$RUNNER_TEMP/recovery-input/candidate.zip" | sha256sum --check --status
jq -nc --arg observed "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{schema:1,artifact_id:11412848210,archive_sha256:"ace85260c3389916fe3dcd7ee9cd5b766e4030dd6cee13c7f89285ada79c944f",retrieved_at:$observed}' \
'{schema:1,artifact_id:12664519771,archive_sha256:"2dd253e1f2946ddcb2b8e75ef397596001757ddbcb0a91f717e9505bbf28b4f6",retrieved_at:$observed}' \
> "$RUNNER_TEMP/recovery-input/live-retrieval.json"
- name: Transfer only the verified original inputs
id: transfer
Expand Down Expand Up @@ -92,7 +92,7 @@ jobs:
run: |
python -m unittest test_verify_packages test_release_train
python -O -m unittest test_verify_packages test_release_train
- name: Rehearse all 225 original package pairs with a simulated feed
- name: Rehearse all 231 original package pairs with a simulated feed
run: >-
python scripts/integration-program/run_consolidated_recovery_fixture.py
--inputs "$RUNNER_TEMP/recovery-input"
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
# Images (Docker Hub only; these are the names the old Community publishers used,
# and the names still referenced by the root README, wiki, samples, and docs):
# elsaworkflows/elsa-server-v3 <- docker/ElsaServer.Dockerfile
# elsaworkflows/elsa-studio-v3 <- docker/ElsaStudio.Dockerfile
# elsaworkflows/elsa-server-and-studio-v3 <- docker/ElsaServerAndStudio.Dockerfile
# 3.10 does not publish elsaworkflows/elsa-studio-v3.
#
# Tags:
# every accepted version publishes its exact X.Y.Z or X.Y.Z-preview.N tag
Expand Down Expand Up @@ -159,9 +159,6 @@ jobs:
- name: elsa-server-and-studio
dockerfile: docker/ElsaServerAndStudio.Dockerfile
image: elsaworkflows/elsa-server-and-studio-v3
- name: elsa-studio
dockerfile: docker/ElsaStudio.Dockerfile
image: elsaworkflows/elsa-studio-v3
steps:
- name: Checkout ${{ needs.prepare.outputs.source_ref }}
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
type: boolean
default: false
publish_nuget:
description: Publish a release-tag package to NuGet.org for this run (requires publisher approval). Stable 3.10.x nuget.org publishing is blocked until re-pin (#9016).
description: Publish a release-tag package to NuGet.org for this run (requires publisher approval). Stable 3.10.0 nuget.org publishes the pinned 231-ID candidate.
required: true
type: boolean
default: false
Expand Down Expand Up @@ -374,7 +374,7 @@ jobs:
fi
echo "VERSION=${VERSION}" >> $GITHUB_ENV

# Stable 3.10.x nuget.org is blocked until re-pin (#9016); this job must not pack.
# Stable 3.10.0 nuget.org stages the pinned candidate; this job must not pack.
- uses: actions/setup-dotnet@v4
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.publish_nuget && startsWith(github.ref, 'refs/tags/3.10.') && !contains(github.ref_name, '-')) }}
with:
Expand Down Expand Up @@ -456,7 +456,7 @@ jobs:
# cancel a publish half-done. Move the two together.
timeout-minutes: 30
# NuGet publication requires an explicit dispatch on a release tag. Stable
# 3.10.x is blocked until re-pin (#9016); other tags push this run's pack.
# 3.10.0 stages the pinned candidate; other tags push this run's pack.
if: ${{ github.event_name == 'workflow_dispatch' && inputs.publish_nuget && startsWith(github.ref, 'refs/tags/') }}
permissions:
contents: read
Expand All @@ -478,7 +478,7 @@ jobs:

- name: Download Packages
# Pinned for the reason given on the checkout above. Skipped for stable
# 3.10.x, which stages the current pin and fails the 231-ID guard until #9016.
# 3.10.0, which stages the pinned 231-ID candidate.
if: ${{ !(startsWith(github.ref, 'refs/tags/3.10.') && !contains(github.ref_name, '-')) }}
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
Expand Down
Loading
Loading