Sign Windows forkpress binaries with Azure Trusted Signing in BK#386
Open
mokagio wants to merge 2 commits into
Open
Sign Windows forkpress binaries with Azure Trusted Signing in BK#386mokagio wants to merge 2 commits into
mokagio wants to merge 2 commits into
Conversation
9c0626a to
ee7027f
Compare
There was a problem hiding this comment.
Pull request overview
This PR replaces the Windows signing placeholder with Azure Trusted Signing and wires signing into the Buildkite Windows build, while also expanding ForkPress’ COW/merge, remote-site cloning, and plugin-compatibility tooling/documentation.
Changes:
- Implement Azure Trusted Signing for Windows artifacts and exercise signing in BK Windows CI.
- Add macOS codesigning + notarization helper scripts and integrate signing/notarization in BK mac builds.
- Expand COW merge capabilities and test coverage (stale-audit/revalidation, router/admin UX paths, MySQL export/import to SQLite, plugin compatibility manifest + docs updates).
Reviewed changes
Copilot reviewed 68 out of 74 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| vendor/wordpress-php-toolkit/components/Git/Protocol/Parser/class-protocoldemultiplexer.php | Adjust Git protocol demuxing to handle unmultiplexed PACK streams across chunks. |
| tests/cow/stale_audit.php | Extend stale-audit fixtures (runs-only audit, restored reviews, bulk apply + revalidation scenarios). |
| tests/cow/schema_review.php | Add merge CLI helper + new schema drift/revalidation fixtures and filters. |
| tests/cow/router_paths.php | Add coverage for wp-admin plugin install/update routing and legacy redirects. |
| tests/cow/router_branch_actions.php | Add coverage for non-async/admin-page merge action and CLI argv auditing. |
| tests/cow/mysql_import.php | New focused test for MySQL JSONL → SQLite import behavior. |
| tests/cow/merge.php | Extend merge suite with scoped crash recovery + after-revalidate resolution expectations. |
| tests/cow/media_validator.php | Expand media validator fixtures (invalid shapes, WordPress semantic upload conflicts, MIME/filesize drift). |
| tests/cow/id_bands.php | Add fixtures for plain INTEGER PRIMARY KEY parent/child collision guarding + reset-band import guard. |
| tests/cow/git_server.php | Add tests for PACK demux tail handling + missing branch DB invariant enforcement. |
| tests/cow/filesystem.php | Add after-revalidate coverage for binary file conflict source drift. |
| tests/cow/explicit_ids.php | Add explicit-ID graph fixtures (post_parent, logical identity unique collision, exhausted band refresh). |
| tests/cow/branch_ui.php | Extend wp-admin branch UI test harness for history/tree/admin page rendering + menu registration. |
| scripts/windows/sign.ps1 | Replace PFX signing with Azure Trusted Signing via signtool /dlib + strict env validation. |
| scripts/popular-plugin-install-smoke.php | New smoke script to download/unpack popular plugin zips and validate package shape + headers. |
| scripts/popular-plugin-compat.test.mjs | Add Node test to validate the popular-plugin compatibility manifest. |
| scripts/popular-plugin-compat.mjs | Add manifest refresh/validate CLI for WordPress.org top-100 popular plugins. |
| scripts/macos/sign-and-notarize.sh | New helper to codesign then notarize a macOS binary (optional skip). |
| scripts/macos/notarize.sh | New helper to submit a zipped binary to notarytool and fetch logs on failure. |
| scripts/macos/entitlements.plist | Add (currently empty) hardened-runtime entitlements file. |
| scripts/macos/codesign.sh | New helper to codesign with hardened runtime + timestamp and verify signature. |
| scripts/dev/cow-changed-test-plan.sh | Add --jobs parallelism for local changed-test-plan execution + log capture. |
| scripts/cow/mysql_import_sqlite.php | New MySQL JSONL import tool to create/populate SQLite + indexes. |
| scripts/cow/mysql_export.php | New remote MySQL exporter producing JSONL (tables/indexes/rows) without booting WP. |
| scripts/cow/git_server.php | Make missing branch DB on existing-branch update a hard error (enforced invariant). |
| runtime/cow/router.php | Redirect legacy plugin install/update routes to wp-admin equivalents when appropriate. |
| runtime/cow/bootstrap_wp.php | Preserve existing $table_prefix and enable wp-admin plugin install/update prerequisites. |
| README.md | Add installation quick-start improvements + remote-site overview and links. |
| package.json | Add mermaid support + manifest validation test; bump Astro; add packageManager. |
| Makefile | Add MySQL import test target and new e2e selector target; include mysql import in fast set. |
| installer/windows/ForkPress.iss | Bump Windows installer version macro. |
| experiments/branchfs/runtime/managed_wp_files.php | Align branchfs wp-config defaults with COW bootstrap (FS_METHOD, mods/http flags). |
| experiments/branchfs/runtime/bootstrap_wp.php | Align branchfs bootstrap wp-config defaults with COW bootstrap (FS_METHOD, mods/http flags). |
| docs/top-plugin-support.md | Document top-100 plugin compatibility target + refresh/validate + smoke testing. |
| docs/stale-audit-workflow.md | Update stale-audit workflow doc for expanded after-revalidate support and bulk apply behavior. |
| docs/remote-sites.md | New guide for remote-site cloning, thin/full sync, MySQL import, and plugin installs. |
| docs/plugin-validator-recipes.md | New practical plugin validator recipe guide (graphs, identities, driver rules, tests). |
| docs/plugin-merge-validators.md | Cross-link to recipes/top-plugin support and expand semantic fixture descriptions. |
| docs/merging.md | Add branch history/tree UX docs and update conflict-queue command references. |
| docs/merge-test-speed.md | Document --jobs parallel changed-test-plan and CI/release-matrix rationale. |
| docs/merge-crash-consistency.md | Document scoped crash recovery + expand crash/rollback coverage notes. |
| docs/documentation-site.md | Document Mermaid diagram support and integration ordering requirement. |
| docs/conflict-review.md | New end-to-end conflict review workflow guide (history/tree/queues/revalidate/after-revalidate). |
| docs/commands.md | Add references to conflict-review and remote-sites docs; add history/tree/conflicts commands. |
| docs/branching.md | Add remote-site branching entry point and link to remote-site guide. |
| crates/forkpress-storage/src/remote.rs | Add --force replace-existing branch behavior for remote branching + cleanup flow. |
| crates/forkpress-storage/src/lib.rs | Add external-tree branch creation helper, branch existence check, recreate cleanup, merge --root-host, and test failpoint guard. |
| crates/forkpress-storage/Cargo.toml | Version bump to 0.1.48. |
| crates/forkpress-server/Cargo.toml | Version bump to 0.1.48. |
| crates/forkpress-runtime/Cargo.toml | Version bump to 0.1.48. |
| crates/forkpress-git/Cargo.toml | Version bump to 0.1.48. |
| crates/forkpress-core/Cargo.toml | Version bump to 0.1.48. |
| crates/forkpress-cli/Cargo.toml | Version bump to 0.1.48. |
| crates/forkpress-cli/build.rs | Include MySQL export/import scripts in bundled runtime assets. |
| Cargo.lock | Lockfile updates for crate version bumps. |
| astro.config.mjs | Add astro-mermaid integration and extend docs sidebar navigation. |
| AGENTS.md | Clarify Codex sandbox .git permission failure diagnosis/remediation guidance. |
| .github/workflows/release-verify.yml | Update action versions/caches and switch Windows signing gate to Azure tenant env var. |
| .github/workflows/release-publish.yml | Update action versions/caches and switch Windows signing gate/warnings to Azure tenant env var. |
| .github/workflows/release-prepare.yml | Update checkout action version. |
| .github/workflows/ci.yml | Update checkout/cache action versions across CI jobs. |
| .buildkite/commands/windows-build.ps1 | Build and now sign Windows smoke artifact in BK. |
| .buildkite/commands/mac-x86_64-build.sh | Add sign+notarize step for mac x86_64 BK build. |
| .buildkite/commands/mac-aarch64-build.sh | Codesign before e2e; notarize after e2e for mac aarch64 BK build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
259
to
283
| wait_one_command() { | ||
| local wait_index="${running_indices[0]}" | ||
| local pid="${pids[$wait_index]}" | ||
| local status=0 | ||
| if wait "$pid"; then | ||
| status=0 | ||
| else | ||
| status=$? | ||
| fi | ||
| statuses[$wait_index]=$status | ||
| if [ "$status" -ne 0 ]; then | ||
| failed=1 | ||
| fi | ||
| running_indices=("${running_indices[@]:1}") | ||
| } | ||
|
|
||
| while [ "$next_command" -lt "${#commands[@]}" ] || [ "${#running_indices[@]}" -gt 0 ]; do | ||
| while [ "$next_command" -lt "${#commands[@]}" ] && [ "${#running_indices[@]}" -lt "$JOBS" ]; do | ||
| start_command "$next_command" | ||
| next_command=$((next_command + 1)) | ||
| done | ||
| if [ "${#running_indices[@]}" -gt 0 ]; then | ||
| wait_one_command | ||
| fi | ||
| done |
Comment on lines
+142
to
+151
| function download_zip(array $plugin, string $cache_dir): string { | ||
| $slug = (string)$plugin['slug']; | ||
| $url = (string)($plugin['download_link'] ?? ''); | ||
| if ($url === '') { | ||
| fail("$slug has no download_link"); | ||
| } | ||
| mkdir_p($cache_dir); | ||
| $zip_path = rtrim($cache_dir, '/\\') . '/' . $slug . '.zip'; | ||
| if (is_file($zip_path) && filesize($zip_path) > 0) { | ||
| return $zip_path; |
Comment on lines
+55
to
+57
| $timestampServer = if ($env:AZURE_TIMESTAMP_SERVER) { $env:AZURE_TIMESTAMP_SERVER } else { 'http://timestamp.acs.microsoft.com' } | ||
| $fileDigest = if ($env:AZURE_FILE_DIGEST) { $env:AZURE_FILE_DIGEST } else { 'SHA256' } | ||
| $timestampDigest = if ($env:AZURE_TIMESTAMP_DIGEST) { $env:AZURE_TIMESTAMP_DIGEST } else { 'SHA256' } |
Comment on lines
1
to
+18
| <# | ||
| .SYNOPSIS | ||
| Signs Windows release artifacts when a code-signing certificate is available. | ||
| Signs Windows artifacts with Azure Trusted Signing. | ||
|
|
||
| .DESCRIPTION | ||
| SHA256-only Authenticode signing via `signtool.exe /dlib /dmdf`. No PFX | ||
| fallback — forkpress is a new app with a single signing identity, so the | ||
| script throws loudly when Azure Trusted Signing is not configured rather | ||
| than silently producing unsigned binaries. | ||
|
|
||
| The CI Toolkit plugin's `setup_azure_trusted_signing.ps1` materializes | ||
| `signtool.exe` + the Azure DLib and exports `SIGNTOOL_PATH`, | ||
| `AZURE_CODE_SIGNING_DLIB`, `AZURE_METADATA_JSON`. This script invokes | ||
| the setup once (per process) when those vars aren't already set, then | ||
| signs each `-Files` entry. | ||
|
|
||
| The `/debug` flag is always on: without it, remote auth/quota/network | ||
| failures from Azure collapse to a generic `SignTool Error`. |
Replaces the previous PFX-based `scripts/windows/sign.ps1` with an Azure Trusted Signing implementation and wires it into the BK `windows-build` step so smoke-artifact builds exercise the same signing path the release-publish workflow will use. forkpress is a new app with a single Windows signing identity, so the script intentionally has no PFX fallback: missing Azure env vars throw with a message naming every absent var. `signtool` is always invoked with `/debug` so Azure auth/quota/network failures surface diagnostics instead of collapsing to the generic `SignTool Error` we have been bitten by on Studio and pcd. The CI Toolkit plugin's `setup_azure_trusted_signing.ps1` is what materializes `signtool.exe` + the Azure DLib and exports `SIGNTOOL_PATH`, `AZURE_CODE_SIGNING_DLIB`, `AZURE_METADATA_JSON`. `sign.ps1` resolves it via `Get-Command` and runs it once per process when those vars aren't already set. GHA `release-publish.yml` and `release-verify.yml` switch their conditional gates from `WINDOWS_CODESIGN_CERT_BASE64` / `WINDOWS_CODESIGN_PASSWORD` to `AZURE_TENANT_ID`. The forkpress GHA environment does not currently expose the Azure secrets, so those steps remain no-ops there until the secrets are wired — the warning message is updated accordingly. Smoke-validated locally on macOS: `pwsh` parse-check passes for both scripts, the throw fires with every missing var named, and the `Get-Command setup_azure_trusted_signing.ps1` lookup fails cleanly when the CI Toolkit plugin isn't on PATH. Actual signtool round-trip is Tier 3 — proven only on a BK `windows` agent. --- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Code Opus 4.7 (1M context) <noreply@anthropic.com>
Windows PowerShell 5.1 (BK `windows` queue) reads `.ps1` files as ANSI/Windows-1252 unless a UTF-8 BOM is present, so the em dashes in `sign.ps1`'s `throw` message and the comment in `windows-build.ps1` got decoded as garbage and broke the parser mid-string with cascading "Unexpected token" / "missing terminator" errors during the `windows-tests` `[scriptblock]::Create(...)` syntax check on build #313. Local `pwsh` on macOS (PowerShell Core 7+, UTF-8 native) parsed the same file cleanly, which is why the Tier 2 parse-check missed this. Going forward, scan with `grep -nP "[^\x00-\x7F]" path/to/script.ps1` before pushing PowerShell intended for the Windows queue. --- Generated with the help of Claude Code, https://claude.com/claude-code Co-Authored-By: Claude Code Opus 4.7 (1M context) <noreply@anthropic.com>
7f5534a to
e5526d3
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Stacked on #385.
Rationale
forkpress is a new app, so it adopts Azure Trusted Signing for Windows from day one — no PFX cert to rotate, no fallback path to keep alive. Replaces the PFX placeholder
scripts/windows/sign.ps1and wires signing into the BKwindows-buildstep so the smoke artifact gets the same treatment a release will.Tradeoffs
signtool /debugalways on — verbose, but the only way Azure auth/quota errors surface (Studio #3290 lesson).Gotchas
WINDOWS_CODESIGN_CERT_BASE64toAZURE_TENANT_ID. GHA secrets aren't wired, so those steps stay no-op until they are; BK is where signing actually runs..ps1as ANSI, not UTF-8 — keep these scripts ASCII-only (fix landed in7f5534aafter build [codex] Extend merge revalidation and WordPress semantic guards #313 broke on an em dash).How to test
Get-AuthenticodeSignaturereturnedValid.