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
33 changes: 33 additions & 0 deletions .github/workflows/php-transformer-dev-trunk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: PHP Transformer dev-trunk mirror

on:
push:
branches:
- trunk
paths:
- "php-transformer/**"
- ".github/workflows/php-transformer-dev-trunk.yml"

permissions:
contents: read

concurrency:
group: component-release
cancel-in-progress: false

jobs:
mirror:
name: Mirror PHP Transformer trunk
runs-on: ubuntu-latest
if: github.repository == 'Automattic/blocks-engine'

steps:
- uses: Extra-Chill/homeboy-action@v2.19.1
with:
component: php-transformer
version: 0.383.4
commands: git subtree php-transformer ${{ github.sha }} --apply --branch-only
ssh-key: ${{ secrets.PHP_TRANSFORMER_MIRROR_DEPLOY_KEY }}
ssh-known-hosts: |
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
ssh-require-known-hosts: true
71 changes: 0 additions & 71 deletions .github/workflows/php-transformer-split.yml

This file was deleted.

101 changes: 101 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Release components

on:
push:
branches:
- trunk
workflow_dispatch:
inputs:
dry-run:
description: Preview the release without changing trunk or publishing packages
type: boolean
default: true

permissions:
contents: write
id-token: write
issues: write
pull-requests: write

concurrency:
group: component-release
cancel-in-progress: false

# Keep these jobs serial. Each Homeboy release may commit version/changelog
# changes and push trunk; the next job must resolve the refreshed trunk tip,
# not the event SHA that started this workflow. Each job's `if: !cancelled()`
# means a sibling's failure never blocks or skips the others — every
# component release attempt runs and reports its own outcome independently.
#
# Pins, and what each one is for (every SHA below was verified by fetching
# the tag directly from its source repo and checking `^{commit}` equality —
# not assumed from the tag name):
#
# - `uses: .../release.yml@v2.19.1` selects the released revision of the
# reusable release workflow itself.
# - `action-ref: v2.19.1` is the homeboy-action revision that workflow
# checks out into `.homeboy-action` for the composite action steps. Kept
# in lockstep with the `uses:` pin above. v2.19.1 is released and contains
# v2.19.0 (the previously pinned candidate commit
# b2ff19a4e71772a1d6b376b7c0bf00d8ef3415cc) plus two additional merged,
# released fixes (homeboy-action#490, #491); no unreleased commits.
# - `extension-ref` pins the homeboy-extensions monorepo commit each job's
# declared extension installs from. It is required, not optional: the
# installed homeboy CLI's `install_for_component` path clones the
# extension source with no revision when `extension-ref` is empty,
# landing on whatever the source's default branch currently is rather
# than a released extension version (verified by reading
# crates/homeboy-core/src/extension/lifecycle/{mod,install_sources}.rs at
# Homeboy v0.383.4). Each job is pinned to the release tag for the
# extension IT ACTUALLY DECLARES, not the previous candidate SHA reused
# across all three jobs regardless of which extension a job needs:
# - php/figma declare `wordpress` (see their homeboy.json) → pinned to
# `wordpress-v3.48.6`, whose peeled commit
# (7f28a979517a96e003d0510d64bc5139c259837d) is exactly the earlier
# candidate SHA — same content, now referenced by its released tag.
# - javascript declares `nodejs` (see packages/blocks-engine/homeboy.json)
# → pinned to `nodejs-v3.7.4`, this repo's own extension, not the
# wordpress tag the previous candidate SHA happened to also contain a
# valid (but non-current) snapshot of.
jobs:
javascript:
uses: Extra-Chill/homeboy-action/.github/workflows/release.yml@v2.19.1
with:
component: packages/blocks-engine
action-ref: v2.19.1
extension-ref: nodejs-v3.7.4
prepared-ref: trunk
dry-run: ${{ inputs.dry-run || false }}
release-branch: trunk
secrets: inherit

php:
needs: javascript
if: ${{ !cancelled() }}
uses: Extra-Chill/homeboy-action/.github/workflows/release.yml@v2.19.1
with:
component: php-transformer
action-ref: v2.19.1
extension-ref: wordpress-v3.48.6
prepared-ref: trunk
dry-run: ${{ inputs.dry-run || false }}
release-branch: trunk
publisher-known-hosts: |
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
secrets:
HOMEBOY_APP_ID: ${{ secrets.HOMEBOY_APP_ID }}
HOMEBOY_APP_PRIVATE_KEY: ${{ secrets.HOMEBOY_APP_PRIVATE_KEY }}
PUBLISH_SSH_KEY: ${{ secrets.PHP_TRANSFORMER_MIRROR_DEPLOY_KEY }}

figma:
needs: php
if: ${{ !cancelled() }}
uses: Extra-Chill/homeboy-action/.github/workflows/release.yml@v2.19.1
with:
component: figma-transformer
action-ref: v2.19.1
extension-ref: wordpress-v3.48.6
prepared-ref: trunk
dry-run: ${{ inputs.dry-run || false }}
release-branch: trunk
secrets: inherit
80 changes: 80 additions & 0 deletions docs/release-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Component Releases

The `release.yml` workflow runs the three package components in dependency
order on `trunk`. Jobs are serialized because Homeboy may commit version and
changelog updates; each later job resolves the refreshed trunk tip.

## Native Publication

- `@automattic/blocks-engine` publishes through the Node.js Homeboy extension.
- `php-transformer` creates its WordPress release archive and publishes the
`php-transformer/` prefix to
`Automattic/blocks-engine-php-transformer`. Its source
`php-transformer-vX.Y.Z` tag becomes `vX.Y.Z` in the mirror.
- `figma-transformer` retains GitHub tag/archive release while registry
publication remains disabled until standalone Packagist provisioning in
#1364 exists.

The `php-transformer-dev-trunk.yml` workflow mirrors the package's `trunk`
branch with one supported `homeboy-action` invocation. Credentials and host
verification are owned by the action; the consumer does not configure an
ssh-agent, write keys or known hosts, or run `git push`.

Blocks Engine does not notify Static Site Importer or any other consumer. The
repositories are decoupled: consumers resolve published coordinates from the
mirror repository, npm registry, or release tags themselves.

## Pins

The workflow uses released tags, verified by resolving each tag's peeled
commit directly:

| Capability | Repository | Pinned tag | Peeled commit |
| --- | --- | --- | --- |
| Component release workflow and native Git operation routing | `Extra-Chill/homeboy-action` | `v2.19.1` | `d9c6d0ee1560612f55645b4b94d0f45ae7dba9b3` |
| `nodejs` extension | `Extra-Chill/homeboy-extensions` | `nodejs-v3.7.4` | `c9a119745e5d961dccb0206e1231faa01c62f0ae` |
| `wordpress` extension | `Extra-Chill/homeboy-extensions` | `wordpress-v3.48.6` | `7f28a979517a96e003d0510d64bc5139c259837d` |

Each `extension-ref` matches the extension declared by that component. The
pin is required because an empty extension revision floats to the extension
repository's default branch rather than a released version.

## Subtree Verification

Native Git subtree publication (`homeboy git subtree`) is available in
released Homeboy `v0.383.4`. Verification used the actual release
binary and disposable local bare repositories. Preview exited 0 without
creating refs; `--apply` exited 0 and published a tree identical to the
source subtree; a re-run reported `already-identical`; `--branch-only` left
tags untouched; normal mode published the configured tag; and sibling
components remained excluded. The success-path serialization failure found
in Homeboy `v0.383.0` is fixed in `v0.383.4`.

The historical `backfill.sh` remains only as disaster recovery after loss of
the mirror repository. It calls the same native Homeboy subtree command for
each historical `php-transformer-v*` source tag and for `origin/trunk`; routine
trunk mirroring uses the workflow above.

## Registry Credentials

The PHP subtree destination uses the existing
`PHP_TRANSFORMER_MIRROR_DEPLOY_KEY` repository secret through the action's
`ssh-key` input. GitHub host verification is pinned in the workflow.

Npm publication for the JavaScript package remains blocked on the upstream
credential contract tracked in `Extra-Chill/homeboy-action#492`. No released
contract report was available while updating this PR, so no raw consumer-side
`npm publish` step is added. After an action release carries that contract,
operators must provision the repository's npm publishing credential or trusted
publishing configuration according to that released contract.

## Activation Checklist

- `PHP_TRANSFORMER_MIRROR_DEPLOY_KEY` in `Automattic/blocks-engine`, with
write access to `Automattic/blocks-engine-php-transformer`.
- `HOMEBOY_APP_ID` and `HOMEBOY_APP_PRIVATE_KEY` are optional; provision them
only if release commits and tags should use a GitHub App identity.
- Npm credentials remain blocked until the released action contract exists.

No merge, release, publication, tag, or secret change is performed by this
repository change.
6 changes: 6 additions & 0 deletions figma-transformer/homeboy.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
"changelog_target": "CHANGELOG.md",
"id": "figma-transformer",
"remote_path": "",
"extensions": {
"wordpress": {}
},
"release": {
"publish": false
},
"version_targets": [
{
"file": "VERSION",
Expand Down
6 changes: 6 additions & 0 deletions packages/blocks-engine/homeboy.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
"changelog_target": "CHANGELOG.md",
"id": "blocks-engine",
"remote_path": "",
"extensions": {
"nodejs": {}
},
"release": {
"publish": true
},
"version_targets": [
{
"file": "package.json",
Expand Down
4 changes: 2 additions & 2 deletions php-transformer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Run the real WordPress materialization integration against a standard WordPress

## Release Consumption

The package lives in a subtree of the Blocks Engine repository. Composer cannot discover a package whose `composer.json` is below the repository root from a plain monorepo VCS tag, so releases are published through an automated subtree split: `.github/workflows/php-transformer-split.yml` pushes package-only history to [`Automattic/blocks-engine-php-transformer`](https://github.com/Automattic/blocks-engine-php-transformer), translating each `php-transformer-vX.Y.Z` monorepo tag to `vX.Y.Z` on the mirror. Packagist indexes the mirror.
The package lives in a subtree of the Blocks Engine repository. Composer cannot discover a package whose `composer.json` is below the repository root from a plain monorepo VCS tag, so releases are published through Homeboy's native subtree publisher to [`Automattic/blocks-engine-php-transformer`](https://github.com/Automattic/blocks-engine-php-transformer), translating each configured monorepo release to the corresponding `vX.Y.Z` mirror tag. Packagist indexes the mirror.

This package intentionally omits `replace` and `provide` declarations for the older downstream package names. Those packages expose their own WordPress plugin bootstraps, functions, hooks, CLI commands, abilities, and product-shaped reports, so the canonical transformer package should not satisfy their Composer requirements directly.

Expand Down Expand Up @@ -238,7 +238,7 @@ Operator-only release checklist after the release-readiness PR merges:
- Update downstream wrapper/product PRs from review-only constraints to tagged constraints.
- Decide whether GitHub Releases are part of this first package publication path.

Homeboy owns the local release preflight for this package through `php-transformer/homeboy.json`. Run Homeboy with `php-transformer/` as the component path so release automation detects the monorepo path and uses `php-transformer-v*` tags, without adding wrapper-package names to this package metadata.
Homeboy owns the local release preflight and subtree publication for this package through `php-transformer/homeboy.json`. Run Homeboy with `php-transformer/` as the component path so release automation detects the monorepo path and uses `php-transformer-v*` tags, without adding wrapper-package names to this package metadata.

Recommended post-merge dry-run:

Expand Down
9 changes: 7 additions & 2 deletions php-transformer/docs/consumer-prs/packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,13 @@ Before any downstream PR merges, replace draft branch constraints with a tagged

`automattic/blocks-engine-php-transformer` is published to Packagist through an automated subtree split. The read-only mirror repository is `Automattic/blocks-engine-php-transformer`; Packagist indexes the mirror, never the monorepo.

- `.github/workflows/php-transformer-split.yml` splits `php-transformer/` with `git subtree split` and pushes to the mirror: trunk pushes update the mirror `trunk` (installable as `dev-trunk`), and `php-transformer-vX.Y.Z` tag pushes create translated `vX.Y.Z` mirror tags, which become Packagist releases.
- The workflow authenticates with a deploy key on the mirror, stored as the `PHP_TRANSFORMER_MIRROR_DEPLOY_KEY` Actions secret in `Automattic/blocks-engine`.
- `.github/workflows/php-transformer-dev-trunk.yml` invokes released Homeboy
`git subtree` support to update the mirror `trunk` (installable as
`dev-trunk`). Component releases publish translated `vX.Y.Z` mirror tags
through the native `release.subtree` configuration.
- The action authenticates with a deploy key on the mirror, stored as the
`PHP_TRANSFORMER_MIRROR_DEPLOY_KEY` Actions secret in
`Automattic/blocks-engine`.
- `php-transformer/.gitattributes` keeps dist archives lean. The dist carries what a consumer can call plus the contracts describing what those calls return, so `src/`, `resources/`, and `docs/contracts/` ship while the diagnostic and parity harness does not. Harness code lives in `dev/`, mapped through `autoload-dev` rather than the shipped `autoload` block, so an installed package cannot resolve it even where a Composer path repository copies the working tree verbatim.
- `tests/packaging/dist-shape.php` asserts that shape against `git archive` directly, since no other suite observes export-ignore: parity and contract runs read the working tree, and the install proof's path repository copies it wholesale.
- The mirror is not a support surface: issues stay disabled there, `composer.json` `support.issues` points at `Automattic/blocks-engine`, and the package README banner marks the mirror read-only.
Expand Down
16 changes: 16 additions & 0 deletions php-transformer/homeboy.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
"changelog_target": "CHANGELOG.md",
"id": "php-transformer",
"remote_path": "",
"extensions": {
"wordpress": {}
},
"release": {
"publish": true,
"subtree": [
{
"prefix": "php-transformer",
"remote": "git@github.com:Automattic/blocks-engine-php-transformer.git",
"branch": "trunk",
"tag": true,
"tag_template": "v{version}",
"branch_policy": "fast_forward"
}
]
},
"version_targets": [
{
"file": "VERSION",
Expand Down
Loading
Loading