-
Notifications
You must be signed in to change notification settings - Fork 19
Add release-mageos orchestration skill #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
marcelmtz
wants to merge
1
commit into
mage-os:main
Choose a base branch
from
marcelmtz:feat/release-orchestration-skill
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,195 @@ | ||
| --- | ||
| name: release-mageos | ||
| description: Orchestrate a full Mage-OS release — preflight gate checks, preview build, artifact verification, production build, and all the release artifacts (GitHub release, website post, social copy). Use when the user is shipping a Mage-OS version and wants the whole process driven, e.g. "release 3.4.0", "let's ship 3.5.0", "run the release process", "what's left for the release". Also use for the individual phases ("run release preflight", "verify the built packages against 3.3.0"). | ||
| --- | ||
|
|
||
| # Release a Mage-OS Version | ||
|
|
||
| Drives a Mage-OS release end to end as a **gated checklist**, not an unattended script. Each phase verifies its preconditions, does the mechanical work, and stops at points where a human has to decide. | ||
|
|
||
| This skill sequences the existing release skills rather than replacing them: | ||
|
|
||
| | Phase | Delegates to | | ||
| |---|---| | ||
| | Preview analysis | [[analyze-release-preview]] | | ||
| | History files | [[add-release-history]] | | ||
| | Branch coverage (major/minor only) | [[audit-release-branches]], [[prep-release-prs]] | | ||
| | Maintainer status update | [[summarize-release-status]] | | ||
|
|
||
| ## Required inputs | ||
|
|
||
| 1. **Target version** (e.g. `3.4.0`) | ||
| 2. **Upstream Magento version** (e.g. `2.4.9`) | ||
|
|
||
| Determine the previous version automatically from `repo.mage-os.org` — highest published version below the target. Confirm with the user at a major-version boundary. | ||
|
|
||
| **Upstream version gotcha:** Adobe ships some security fixes as *isolated patches* (e.g. `249-2026-08-001-CE`) rather than tagged releases. When that happens there is **no new upstream tag** and `upstream_release` stays at the current value. Check `magento/magento2` tags before assuming a bump. Getting this wrong silently produces a wrong `extra.magento_version` in every metapackage. | ||
|
|
||
| --- | ||
|
|
||
| ## Phase 1 — Preflight gates | ||
|
|
||
| ```bash | ||
| ./.claude/skills/release-mageos/scripts/preflight.sh <TARGET_VERSION> [UPSTREAM_VERSION] | ||
| ``` | ||
|
|
||
| Checks, in order: | ||
|
|
||
| 1. **Previous release's history files are merged.** If `resource/history/mage-os/*/<PREV>.json` is missing, **stop**. Building without them makes the previous release's packages drift on rebuild. This is the single most important gate. | ||
| 2. **Target tag does not already exist** in `mage-os/mageos-magento2` — guards against re-releasing. | ||
| 3. **Target is not already published** on repo.mage-os.org. | ||
| 4. **supported-version matrix entry exists** for the target in `mage-os/github-actions@main` — *and* `supported-version/dist/index.js` actually contains it. The source JSON being right does not mean the bundle was rebuilt; `dist/` is what CI consumes. | ||
| 5. **`gh` is authenticated as the collaborator account.** Two accounts are usually configured; `marcelmtz` is the collaborator, `marcelswiftotter` gets "must be a collaborator" on PR create/edit. | ||
| 6. **Bundled-repo survey** — which repos have commits since the previous tag. | ||
|
|
||
| Any FAIL blocks the release. WARNs are judgment calls — surface them and ask. | ||
|
|
||
| > **Do not trust the repo survey's commit counts.** `push-release-tag.yml` creates a `Release X.Y.Z` commit that is not on `main`, so tags sit on a diverged lineage and `git compare <tag>...main` reports commits as "ahead" that already shipped. It is a *hint about where to look*, never evidence. Phase 3 is what actually establishes what changed. | ||
|
|
||
| ## Phase 2 — Preview build | ||
|
|
||
| Dispatch **Build, deploy & check Release** (`.github/workflows/build-mageos-release.yml`): | ||
|
|
||
| | Input | Value | | ||
| |---|---| | ||
| | `repo` | `https://preview-repo.mage-os.org/` | | ||
| | `remote_dir` | `/var/www/preview-repo.mage-os.org/html/` | | ||
| | `mageos_release` | target version | | ||
| | `upstream_release` | upstream version | | ||
| | `publish_tag` | **false** | | ||
|
|
||
| Poll until complete. Confirm the **Publish release tag** job is `skipped` — if it ran, the wrong inputs were used. | ||
|
|
||
| Then run [[analyze-release-preview]]. | ||
|
|
||
| **Known non-finding:** the installation-check matrix is built from *published* versions, so it never covers the version being released. Every green preview has this hole. Do not report it as a pass for the new version; recommend a manual `composer create-project` against the preview repo. | ||
|
|
||
| ## Phase 3 — Artifact verification | ||
|
|
||
| The load-bearing phase. Proves what actually shipped, independent of git history. | ||
|
|
||
| ```bash | ||
| php ./.claude/skills/release-mageos/scripts/verify-packages.php <PREV> <NEW> \ | ||
| --packages=module-cms,module-review,module-catalog | ||
| # or, for the definitive full sweep (slow — downloads every package twice): | ||
| php ./.claude/skills/release-mageos/scripts/verify-packages.php <PREV> <NEW> --all | ||
| ``` | ||
|
|
||
| For each package it downloads the previous published zip and the new one, unzips both, and diffs, ignoring `composer.json` (which always differs by version bump). Output is the set of packages with **real content changes**. | ||
|
|
||
| Use it to confirm: | ||
|
|
||
| - Every change intended for this release is present in a built package | ||
| - Nothing unexpected changed | ||
| - Packages that *look* changed from commit counts are actually identical | ||
|
|
||
| Start from the PRs the release is supposed to contain, map each to its package, and verify. Anything in the diff that no PR explains needs an answer before shipping. | ||
|
|
||
| ## Phase 4 — Human gate | ||
|
|
||
| Present: the dependency diff, the verified content changes, contributors, and any behavior changes needing release-note treatment. **Wait for explicit go/no-go.** Do not dispatch the production build on inference. | ||
|
|
||
| ## Phase 5 — Production build | ||
|
|
||
| Same workflow, with: | ||
|
|
||
| | Input | Value | | ||
| |---|---| | ||
| | `repo` | `https://repo.mage-os.org/` | | ||
| | `remote_dir` | `/var/www/repo.mage-os.org/html/` | | ||
| | `publish_tag` | **true** | | ||
|
|
||
| `publish_tag: true` triggers `push-release-tag.yml`, which creates and pushes the version tag in every source repo. **There is no manual tagging step.** | ||
|
|
||
| The deploy job is gated to `["vinai", "rhoerr", "marcelmtz", "mage-os-ci"]`. | ||
|
|
||
| Afterwards confirm the target version is live on repo.mage-os.org before continuing. | ||
|
|
||
| ## Phase 6 — Release artifacts | ||
|
|
||
| Generate all of these from **one shared content model** so they cannot drift: | ||
|
|
||
| ### 6a. GitHub release | ||
|
|
||
| Match the previous release exactly: name = bare version, tag = bare version, `prerelease: false`, target `main`. | ||
|
|
||
| ```bash | ||
| gh release create <VERSION> -R mage-os/mageos-magento2 --draft --verify-tag \ | ||
| --title "<VERSION>" --notes-file <notes.md> | ||
| ``` | ||
|
|
||
| Always `--draft` first. `--verify-tag` prevents creating a stray tag. To publish: | ||
|
|
||
| ```bash | ||
| gh release edit <VERSION> -R mage-os/mageos-magento2 --draft=false --latest | ||
| ``` | ||
|
|
||
| `--latest` is required — GitHub does not infer it from the version number, so without it the badge stays on the old release. | ||
|
|
||
| Structure (from the 3.3.0/3.4.0 releases): header (`**Released:**` / `**Upstream:**`) → intro + upgrade command → Security → Fixes → Bundled add-on updates → Upgrade notes → Contributors. | ||
|
|
||
| ### 6b. Website post — `mage-os/mage-os-org` | ||
|
|
||
| **This repo is forked.** Verify remotes before branching: | ||
|
|
||
| - `origin` → the user's fork (`marcelmtz/mage-os-org`) | ||
| - `source` → upstream (`mage-os/mage-os-org`) — note it is **not** called `upstream` | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These won't be true for everyone -- but probably works for this purpose. Maybe we can make the remote aliases more generic. |
||
|
|
||
| Branch from **`source/main`**, never `origin/main` — the fork's main is routinely dozens of commits stale. Push to `origin`, open the PR against `mage-os/mage-os-org`. | ||
|
|
||
| ```bash | ||
| git fetch source && git checkout -b release/<X-Y-Z>-announcement source/main | ||
| ``` | ||
|
|
||
| File: `src/data/post/YYYY-MM-DD-mage-os-<x>-<y>-<z>-release.md`. Copy the previous release post's frontmatter shape; release posts use `~/assets/images/blog/2026/New-Mage-OS-Website.png` and `author: mage-os-team`. | ||
|
|
||
| Post URL is `/<category-slug>/<filename-stem>` with **no trailing slash** (`trailingSlash: false`), so: | ||
| `https://mage-os.org/releases/YYYY-MM-DD-mage-os-<x>-<y>-<z>-release` | ||
|
|
||
| Sections: intro → Security → Other fixes → Upgrade notes → Our foundation (upstream base, certified stack, previous version EOL) → Thanks → How to upgrade. | ||
|
|
||
| ### 6c. Social copy | ||
|
|
||
| **LinkedIn** — plain text only; LinkedIn strips Markdown, so `**bold**` renders as literal asterisks. Use `→` for bullets. Longer, contextual, hashtags at the end. | ||
|
|
||
| **Discord** — Markdown renders. Keep it tight, include the copy-pasteable upgrade command, and wrap URLs in `<...>` to suppress duplicate embed cards. | ||
|
|
||
| **Ordering:** the website PR must be merged and the site rebuilt *before* the GitHub release is published or anything is posted — the announcement URL is referenced in all of them and 404s until then. | ||
|
|
||
| ## Phase 7 — Post-release | ||
|
|
||
| Run [[add-release-history]] for the new version. It only works after the production build, since it reads published package metadata. **That PR must merge before the next release builds** — it is the Phase 1 gate for the following release. | ||
|
|
||
| --- | ||
|
|
||
| ## Contributors | ||
|
|
||
| Build the list from **two** sources, not one: | ||
|
|
||
| 1. Commit authors across the bundled repos since the previous tag | ||
| 2. **Release-engineering work**, which is invisible to `git log` on the content repos — history-file PRs, supported-version matrix entries, build dispatch, patch porting | ||
|
|
||
| Missing the second category is the default failure mode. Ask who drove the release machinery before finalizing. | ||
|
|
||
| Order the list alphabetically, case-insensitive, matching previous posts. | ||
|
|
||
| ## Security releases | ||
|
|
||
| - If the release ports an Adobe isolated patch, link the bulletin (`APSBxx-xx`) for CVEs and severities rather than restating them. Do not invent CVE identifiers or CVSS vectors — if the bulletin is unreachable, leave them out and say so. | ||
| - **Never assume attack prerequisites from the class of fix.** Check what the controller actually is: `Controller\Adminhtml\*` is admin, `Controller\Account\*` is storefront. A blanket "requires an authenticated admin session" is wrong the moment one fix is storefront-facing or unauthenticated. | ||
| - Call out behavior changes prominently, in both intro and upgrade notes, when a fix removes capability that admins currently have. Where the relevant permissions already exist in the previous release, say so — merchants can then fix their roles *before* upgrading. | ||
| - If a bulletin lists more issues than the release ships, address the gap explicitly or point at the bulletin without implying completeness. | ||
|
|
||
| ## Known traps | ||
|
|
||
| | Trap | Reality | | ||
| |---|---| | ||
| | `git compare <tag>...main` | Lies — release commits sit on a diverged lineage. Diff published artifacts. | | ||
| | `dist/index.js` in github-actions | Must be verified to contain new data; source JSON alone is not enough. | | ||
| | `mage-os-org` remotes | `origin` = fork (often stale), `source` = upstream. | | ||
| | `gh` account | Two configured; only the collaborator can create/edit PRs. | | ||
| | Composer `audit.block-insecure` | Breaks integrity checks when an advisory hits a pinned dep. `COMPOSER_NO_AUDIT=1` does **not** disable it — only `composer config audit.block-insecure false`. | | ||
| | Installation-check matrix | Never covers the version being released. | | ||
| | Isolated patches | No upstream tag; `upstream_release` does not move. | | ||
| | `--latest` on release publish | Not inferred from the version number. | | ||
| | Exact version pins | Core packages are pinned exactly, so per-package upgrades need inline aliases and are rarely practical advice. | | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will get stale over time, should be left out