1
0
mirror of https://github.com/php/pie.git synced 2026-03-23 23:12:17 +01:00

Modify release workflow to allow immutable releases

Instead of creating the release by hand and then having a workflow triggered
to add the release, which is not possible if immutable releases are enabled,
we will now:

 - run the release workflow on "tag" instead of "release"
 - the workflow creates a DRAFT release based on the tag that triggered
 - the workflow then attaches the PHAR to the release
 - maintainer must then review the release, ensure it is correct, then publish

Once the release is published (assuming immutable releases are enabled):

 - the tag is immutable
 - the attached assets on the release are immutable
 - the flag that dictates pre-release/latest release status is immutable
 - the release changelog may still be changed
 - the release title may still be changed
 - a release attestation is added to the release which can be verified

The release can be verified with:

```shell
gh release verify <release-tag>
```

A given `pie.phar` on your machine can be verified as the release asset with:

```shell
gh release verify-asset <release-tag> pie.phar
```

For more documentation, see:
https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
This commit is contained in:
James Titcumb
2025-11-04 16:37:00 +00:00
parent c1fc730eda
commit 458bf2d4f4
4 changed files with 105 additions and 10 deletions

View File

@@ -65,7 +65,9 @@
<ul class="nav nav-pills" id="docs-side-nav">
{% for page in pages %}
{% if page.slug != 'pie-maintainers-handbook' %}
<li class="nav-item"><a href="#docs/{{ page.slug }}" class="nav-link fragmentRoute">{{ page.title }}</a></li>
{% endif %}
{% endfor %}
</ul>
</header>
@@ -73,9 +75,11 @@
<section id="docs" class="tab-content"><div id="docs-content">
{% for page in pages %}
{% if page.slug != 'pie-maintainers-handbook' %}
<section id="docs/{{ page.slug }}" class="container my-md-4 bd-layout hidden">
{{ page.content|preg_replace('~\./docs/~', '')|raw }}
</section>
{% endif %}
{% endfor %}
</div></section>

View File

@@ -1,9 +1,9 @@
name: "Publish the PHAR for Releases"
name: "Publish a draft release with PHAR attached"
on:
release:
types:
- published
push:
tags:
- '*'
permissions:
contents: read
@@ -17,10 +17,32 @@ jobs:
attestations: write
uses: ./.github/workflows/build-phar.yml
release-phar:
create-draft-release:
runs-on: ubuntu-latest
needs:
- build-phar
permissions:
# contents:write is required to create the draft release
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-tags: 'true'
ref: ${{ github.ref }}
# The changelog is generated locally using jwage/changelog-generator and
# that forms the signed tag body. The `--notes-from-tag` option below
# will copy the release notes from the tag so it will contain the changelog
# Note we must create a *draft* release first, to allow attaching assets
# before the release is finalised when using immutable releases.
- name: Create draft release from tag
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "${{ github.ref_name }}" --title "${{ github.ref_name }}" --draft --notes-from-tag
release-phar:
runs-on: ubuntu-latest
needs:
- create-draft-release
permissions:
# contents:write is required to upload the binaries to the release.
contents: write
@@ -33,11 +55,15 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
run: gh attestation verify pie.phar --repo ${{ github.repository }}
- name: Upload binaries to release
uses: softprops/action-gh-release@v2
if: ${{startsWith(github.ref, 'refs/tags/') }}
with:
files: pie.phar
# Once the PHAR has been attached to the release, it is ready for review
# before publishing it. Note that if immutable releases are enabled,
# the tag, pre-release/latest release flag, and all assets become
# immutable, so checking this over is a manual exercise.
# More info: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
- name: Attach an asset to the draft release
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "${{ github.ref_name }}" "pie.phar" --clobber
build-and-push-docker-image:
if: ${{ startsWith(github.ref, 'refs/tags/') }}

1
.gitignore vendored
View File

@@ -9,3 +9,4 @@ box.json
box.phar
pie.phar
/docs-package/
CHANGELOG-*.md

View File

@@ -0,0 +1,64 @@
---
title: PIE Maintainers Handbook
order: 3
---
# PIE Maintainers Handbook
## Branching strategy
At the moment, we operate a single `main` branch, and feature branches. In the
future, to better facilitate patch versions, we may switch to a versioned
branching strategy.
## Release process
Make sure you have the latest version to be released, for example, one of:
```shell
# Using git reset (note: discards any local commits on `main`)
git checkout main && git fetch upstream && git reset --hard upstream/main
# or, using git pull (use `--ff-only` to avoid making merge commits)
git checkout main && git pull --ff-only upstream main
```
Prepare a changelog, set the version and milestone to be released, e.g.:
```shell
PIE_VERSION=1.3.0
PIE_MILESTONE=$PIE_VERSION
```
> [!TIP]
> For pre-releases, you can set the version/milestone to be different, e.g.:
>
> ```shell
> PIE_VERSION=1.3.0-alpha.2
> PIE_MILESTONE=1.3.0
> ```
>
> This will tag/release with the `1.3.0-alpha.2` version, but will generate the
> changelog based on the `1.3.0` milestone in GitHub.
Then generate the changelog file:
```shell
composer require --dev -W jwage/changelog-generator --no-interaction
vendor/bin/changelog-generator generate --user=php --repository=pie --milestone=$PIE_MILESTONE > CHANGELOG-$PIE_VERSION.md
git checkout -- composer.*
composer install
```
Check you are happy with the contents of the changelog. Create a signed tag:
```shell
git tag -s $PIE_VERSION -F CHANGELOG-$PIE_VERSION.md
git push upstream $PIE_VERSION
```
The release pipeline will run, which will create a **draft** release, build the
PHAR file, and attach it. You must then go to the draft release on GitHub,
verify everything is correct, and publish the release.
```shell
rm CHANGELOG-$PIE_VERSION.md
```