Skip to content

Commit 458bf2d

Browse files
committed
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
1 parent c1fc730 commit 458bf2d

File tree

4 files changed

+105
-10
lines changed

4 files changed

+105
-10
lines changed

.github/docs/templates/online.twig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,21 @@
6565

6666
<ul class="nav nav-pills" id="docs-side-nav">
6767
{% for page in pages %}
68+
{% if page.slug != 'pie-maintainers-handbook' %}
6869
<li class="nav-item"><a href="#docs/{{ page.slug }}" class="nav-link fragmentRoute">{{ page.title }}</a></li>
70+
{% endif %}
6971
{% endfor %}
7072
</ul>
7173
</header>
7274
</div>
7375

7476
<section id="docs" class="tab-content"><div id="docs-content">
7577
{% for page in pages %}
78+
{% if page.slug != 'pie-maintainers-handbook' %}
7679
<section id="docs/{{ page.slug }}" class="container my-md-4 bd-layout hidden">
7780
{{ page.content|preg_replace('~\./docs/~', '')|raw }}
7881
</section>
82+
{% endif %}
7983
{% endfor %}
8084
</div></section>
8185

.github/workflows/release.yml

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
name: "Publish the PHAR for Releases"
1+
name: "Publish a draft release with PHAR attached"
22

33
on:
4-
release:
5-
types:
6-
- published
4+
push:
5+
tags:
6+
- '*'
77

88
permissions:
99
contents: read
@@ -17,10 +17,32 @@ jobs:
1717
attestations: write
1818
uses: ./.github/workflows/build-phar.yml
1919

20-
release-phar:
20+
create-draft-release:
2121
runs-on: ubuntu-latest
2222
needs:
2323
- build-phar
24+
permissions:
25+
# contents:write is required to create the draft release
26+
contents: write
27+
steps:
28+
- uses: actions/checkout@v4
29+
with:
30+
fetch-tags: 'true'
31+
ref: ${{ github.ref }}
32+
# The changelog is generated locally using jwage/changelog-generator and
33+
# that forms the signed tag body. The `--notes-from-tag` option below
34+
# will copy the release notes from the tag so it will contain the changelog
35+
# Note we must create a *draft* release first, to allow attaching assets
36+
# before the release is finalised when using immutable releases.
37+
- name: Create draft release from tag
38+
env:
39+
GH_TOKEN: ${{ github.token }}
40+
run: gh release create "${{ github.ref_name }}" --title "${{ github.ref_name }}" --draft --notes-from-tag
41+
42+
release-phar:
43+
runs-on: ubuntu-latest
44+
needs:
45+
- create-draft-release
2446
permissions:
2547
# contents:write is required to upload the binaries to the release.
2648
contents: write
@@ -33,11 +55,15 @@ jobs:
3355
env:
3456
GH_TOKEN: ${{ github.token }}
3557
run: gh attestation verify pie.phar --repo ${{ github.repository }}
36-
- name: Upload binaries to release
37-
uses: softprops/action-gh-release@v2
38-
if: ${{startsWith(github.ref, 'refs/tags/') }}
39-
with:
40-
files: pie.phar
58+
# Once the PHAR has been attached to the release, it is ready for review
59+
# before publishing it. Note that if immutable releases are enabled,
60+
# the tag, pre-release/latest release flag, and all assets become
61+
# immutable, so checking this over is a manual exercise.
62+
# More info: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
63+
- name: Attach an asset to the draft release
64+
env:
65+
GH_TOKEN: ${{ github.token }}
66+
run: gh release upload "${{ github.ref_name }}" "pie.phar" --clobber
4167

4268
build-and-push-docker-image:
4369
if: ${{ startsWith(github.ref, 'refs/tags/') }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ box.json
99
box.phar
1010
pie.phar
1111
/docs-package/
12+
CHANGELOG-*.md

docs/pie-maintainers-handbook.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: PIE Maintainers Handbook
3+
order: 3
4+
---
5+
# PIE Maintainers Handbook
6+
7+
## Branching strategy
8+
9+
At the moment, we operate a single `main` branch, and feature branches. In the
10+
future, to better facilitate patch versions, we may switch to a versioned
11+
branching strategy.
12+
13+
## Release process
14+
15+
Make sure you have the latest version to be released, for example, one of:
16+
17+
```shell
18+
# Using git reset (note: discards any local commits on `main`)
19+
git checkout main && git fetch upstream && git reset --hard upstream/main
20+
# or, using git pull (use `--ff-only` to avoid making merge commits)
21+
git checkout main && git pull --ff-only upstream main
22+
```
23+
24+
Prepare a changelog, set the version and milestone to be released, e.g.:
25+
26+
```shell
27+
PIE_VERSION=1.3.0
28+
PIE_MILESTONE=$PIE_VERSION
29+
```
30+
31+
> [!TIP]
32+
> For pre-releases, you can set the version/milestone to be different, e.g.:
33+
>
34+
> ```shell
35+
> PIE_VERSION=1.3.0-alpha.2
36+
> PIE_MILESTONE=1.3.0
37+
> ```
38+
>
39+
> This will tag/release with the `1.3.0-alpha.2` version, but will generate the
40+
> changelog based on the `1.3.0` milestone in GitHub.
41+
42+
Then generate the changelog file:
43+
44+
```shell
45+
composer require --dev -W jwage/changelog-generator --no-interaction
46+
vendor/bin/changelog-generator generate --user=php --repository=pie --milestone=$PIE_MILESTONE > CHANGELOG-$PIE_VERSION.md
47+
git checkout -- composer.*
48+
composer install
49+
```
50+
51+
Check you are happy with the contents of the changelog. Create a signed tag:
52+
53+
```shell
54+
git tag -s $PIE_VERSION -F CHANGELOG-$PIE_VERSION.md
55+
git push upstream $PIE_VERSION
56+
```
57+
58+
The release pipeline will run, which will create a **draft** release, build the
59+
PHAR file, and attach it. You must then go to the draft release on GitHub,
60+
verify everything is correct, and publish the release.
61+
62+
```shell
63+
rm CHANGELOG-$PIE_VERSION.md
64+
```

0 commit comments

Comments
 (0)