Skip to content

Commit 3a44d3d

Browse files
authored
Merge pull request #758 from PHPCSStandards/feature/32-automate-release-process
Publish release checklist and automate release verification
2 parents 799e293 + 224a57f commit 3a44d3d

File tree

3 files changed

+331
-1
lines changed

3 files changed

+331
-1
lines changed

.github/release-checklist.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Release checklist
2+
3+
## Before Release
4+
5+
### General
6+
7+
- [ ] Verify, and if necessary, update the version constraints for dependencies in the `composer.json` - PR #xxx
8+
- [ ] Verify that any new functions have type declarations (ClassName/array/callable) whenever possible.
9+
- [ ] Verify that the license tags all refer to the _new_ organisation and no longer to Squizlabs. (easily overlooked in new files)
10+
- [ ] Verify that `@copyright` tags in new files use `@copyright 20xx PHPCSStandards and contributors`.
11+
12+
### Wiki
13+
14+
- [ ] Fetch changes and check against vandalism.
15+
- [ ] Verify that any new `public` properties are listed on the Customizable Properties page in the Wiki.
16+
- [ ] Verify that any new sniffs which have `public` properties are listed on the Customizable Properties page in the Wiki.
17+
- [ ] Verify that any new CLI options are listed in the Wiki.
18+
- [ ] Verify that any new Reports have a section in the Reports page in the Wiki.
19+
20+
### Majors only
21+
22+
- [ ] Move old changelog entries to `CHANGELOG_OLD.md` file.
23+
- [ ] Verify that everything deprecated during the previous major was removed.
24+
- [ ] Update the wiki for any references to anything deprecated/removed.
25+
- [ ] Change `Config::STABILITY` from "dev" to "stable" for the branch for the new major. - PR #xxx
26+
27+
### Prepare changelog
28+
29+
- [ ] Prepare changelog for the release and submit the PR. - PR #xxx
30+
- Based on the tickets in the milestone.
31+
- Double-check that any issues which were closed by PRs included in the release, have the milestone set.
32+
- Compare with auto-generated release notes to ensure nothing is missed.
33+
- :pencil2: Remember to add a release link at the bottom!
34+
- [ ] Prepare extra sections for the GH release notes.
35+
- Use "New contributors" list from the auto-generated notes.
36+
- Use the milestone to gather the stats.
37+
- Add sponsor link.
38+
- Remove square brackets from all ticket links or make them proper full links (as GH markdown parser doesn't parse these correctly).
39+
- Change all contributor links to full inline links (as GH markdown parser on the Releases page doesn't parse these correctly).
40+
```md
41+
---
42+
43+
### New Contributors
44+
45+
The PHP_CodeSniffer project is happy to welcome the following new contributors:
46+
@...., @....
47+
48+
### Statistics
49+
50+
**Closed**: # issues
51+
**Merged**: ## pull requests
52+
53+
If you like to stay informed about releases and more, follow [@phpcs on Mastodon](https://phpc.social/@phpcs) or [@PHP_CodeSniffer on X](https://x.com/PHP_CodeSniffer).
54+
55+
Please consider [funding the PHP_CodeSniffer project](https://opencollective.com/php_codesniffer). If you already do so: thank you!
56+
```
57+
58+
### Milestone
59+
60+
- [ ] Close the milestone
61+
- [ ] Open a new milestone for the next release
62+
- [ ] If any open PRs/issues which were milestoned for this release did not make it into the release, update their milestone.
63+
64+
65+
## Release
66+
67+
- [ ] Merge the changelog PR.
68+
For now, cherrypick the changelog to the 4.0 branch.
69+
- [ ] Make sure all CI builds for `master` are green.
70+
- [ ] Create a tag for the release & push it.
71+
- [ ] Make sure all CI builds are green.
72+
- [ ] Download the PHAR files from the GH Actions test build page.
73+
- [ ] Sign the PHAR files using:
74+
```bash
75+
gpg -u [email protected] --detach-sign --output phpcs.phar.asc phpcs.phar
76+
gpg -u [email protected] --detach-sign --output phpcbf.phar.asc phpcbf.phar
77+
gpg -u [email protected] --detach-sign --output phpcs-x.x.x.phar.asc phpcs-x.x.x.phar
78+
gpg -u [email protected] --detach-sign --output phpcbf-x.x.x.phar.asc phpcbf-x.x.x.phar
79+
```
80+
- If, for whatever reason, the key is no longer available or has expired:
81+
-> generate a new key following the steps here: <https://phar.io/howto/generate-gpg-key.html>.
82+
-> upload the new key following the steps here: <https://phar.io/howto/uploading-public-keys.html>.
83+
-> update the key information in the README x 3.
84+
-> update the key info in the verify-release GHA workflow.
85+
- [ ] Get the SHA of the files for the phive.xml file
86+
```bash
87+
# Linux
88+
sha256sum ./phpcs-x.x.x.phar
89+
sha256sum ./phpcbf-x.x.x.phar
90+
91+
# Windows
92+
certutil -hashfile ./phpcs-x.x.x.phar SHA256
93+
certutil -hashfile ./phpcbf-x.x.x.phar SHA256
94+
```
95+
- Update the `gh-pages` branch:
96+
- [ ] Add the new release to the `phive.xml` file.
97+
- [ ] Add the versioned PHAR files + keys in PHAR dir.
98+
- [ ] Add the unversioned PHAR files + keys in root dir.
99+
- [ ] Verify the attestations of the PHAR files.
100+
```bash
101+
gh attestation verify phpcs.phar -o PHPCSStandards
102+
gh attestation verify phpcbf.phar -o PHPCSStandards
103+
gh attestation verify phars/phpcs-x.x.x.phar -o PHPCSStandards
104+
gh attestation verify phars/phpcbf-x.x.x.phar -o PHPCSStandards
105+
```
106+
- [ ] Commit & push the changes.
107+
- [ ] Verify that the website regenerated correctly and that the phars can be downloaded.
108+
- [ ] Create a release & copy & paste the changelog to it.
109+
- [ ] Upload the unversioned PHAR files + asc files to the release.
110+
- [ ] Announce the release in the discussions forum by checking the checkbox at the bottom of the release page.
111+
- [ ] Make sure all CI builds are green, including the verify-release workflow.
112+
113+
114+
## After Release
115+
116+
- [ ] Update the version number in the `Config::VERSION` class constant in the `src/Config.php` file to the _next_ (patch) version.
117+
This can always be adjusted again later if needs be if it is decided that the next version will be a minor/major, but at least for dev
118+
it should clearly show that this is bleeding edge/unreleased.
119+
- [ ] Close release announcement in the "Discussions" for previous minors (leave the announcements related to the current minor open).
120+
121+
122+
### Publicize
123+
124+
- [ ] Post on Mastodon about the release (official account).
125+
- [ ] Post on X about the release (official account).
126+
- [ ] Post on LinkedIn (personal account).

.github/workflows/verify-release.yml

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
name: Verify release
2+
3+
on:
4+
# Run whenever a release is published.
5+
release:
6+
types: [published]
7+
# And whenever this workflow is updated.
8+
push:
9+
paths:
10+
- '.github/workflows/verify-release.yml'
11+
pull_request:
12+
paths:
13+
- '.github/workflows/verify-release.yml'
14+
# Allow manually triggering the workflow.
15+
workflow_dispatch:
16+
17+
# Cancels all previous workflow runs for the same branch that have not yet completed.
18+
concurrency:
19+
# The concurrency group contains the workflow name and the branch name.
20+
group: ${{ github.workflow }}-${{ github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
##################################################################################
25+
# Verify the release is available in all the right places and works as expected. #
26+
##################################################################################
27+
verify-available-downloads:
28+
runs-on: ubuntu-latest
29+
30+
# Only run this workflow in the context of this repo.
31+
if: github.repository_owner == 'PHPCSStandards'
32+
33+
strategy:
34+
fail-fast: false
35+
matrix:
36+
download_flavour:
37+
- "Release assets"
38+
- "Unversioned web"
39+
- "Versioned web"
40+
pharfile:
41+
- 'phpcs'
42+
- 'phpcbf'
43+
44+
name: "${{ matrix.download_flavour }}: ${{ matrix.pharfile }}"
45+
46+
steps:
47+
- name: Retrieve latest release info
48+
uses: octokit/[email protected]
49+
id: get_latest_release
50+
with:
51+
route: GET /repos/PHPCSStandards/PHP_CodeSniffer/releases/latest
52+
env:
53+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
55+
- name: "DEBUG: Show API request failure status"
56+
if: ${{ failure() }}
57+
run: "echo No release found. Request failed with status ${{ steps.get_latest_release.outputs.status }}"
58+
59+
- name: Grab latest tag name from API response
60+
id: version
61+
run: |
62+
echo "TAG=${{ fromJson(steps.get_latest_release.outputs.data).tag_name }}" >> "$GITHUB_OUTPUT"
63+
64+
- name: "DEBUG: Show tag name found in API response"
65+
run: "echo ${{ steps.version.outputs.TAG }}"
66+
67+
- name: Set source URL and file name
68+
id: source
69+
shell: bash
70+
run: |
71+
if [[ "${{ matrix.download_flavour }}" == "Release assets" ]]; then
72+
echo 'SRC=https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/latest/download/' >> "$GITHUB_OUTPUT"
73+
echo "FILE=${{ matrix.pharfile }}.phar" >> "$GITHUB_OUTPUT"
74+
elif [[ "${{ matrix.download_flavour }}" == "Unversioned web" ]]; then
75+
echo 'SRC=https://phars.phpcodesniffer.com/' >> "$GITHUB_OUTPUT"
76+
echo "FILE=${{ matrix.pharfile }}.phar" >> "$GITHUB_OUTPUT"
77+
else
78+
echo 'SRC=https://phars.phpcodesniffer.com/phars/' >> "$GITHUB_OUTPUT"
79+
echo "FILE=${{ matrix.pharfile }}-${{ steps.version.outputs.TAG }}.phar" >> "$GITHUB_OUTPUT"
80+
fi
81+
82+
- name: Verify PHAR file is available and download
83+
run: "wget -O ${{ steps.source.outputs.FILE }} ${{ steps.source.outputs.SRC }}${{ steps.source.outputs.FILE }}"
84+
85+
- name: Verify signature file is available and download
86+
run: "wget -O ${{ steps.source.outputs.FILE }}.asc ${{ steps.source.outputs.SRC }}${{ steps.source.outputs.FILE }}.asc"
87+
88+
- name: "DEBUG: List files"
89+
run: ls -Rlh
90+
91+
- name: Verify attestation of the PHAR file
92+
run: gh attestation verify ${{ steps.source.outputs.FILE }} -o PHPCSStandards
93+
env:
94+
GH_TOKEN: ${{ github.token }}
95+
96+
- name: Download public key
97+
env:
98+
FINGERPRINT: "0x689DAD778FF08760E046228BA978220305CD5C32"
99+
run: gpg --keyserver "hkps://keys.openpgp.org" --recv-keys "$FINGERPRINT"
100+
101+
- name: Verify signature of the PHAR file
102+
run: gpg --verify ${{ steps.source.outputs.FILE }}.asc ${{ steps.source.outputs.FILE }}
103+
104+
- name: Setup PHP
105+
uses: shivammathur/setup-php@v2
106+
with:
107+
php-version: 'latest'
108+
ini-values: error_reporting=-1, display_errors=On
109+
coverage: none
110+
111+
# Note: the `.` is in the command to make it work for both PHPCS as well PHPCBF.
112+
- name: Verify the PHAR is nominally functional
113+
run: php ${{ steps.source.outputs.FILE }} . -e --standard=PSR12
114+
115+
- name: Grab the version
116+
id: asset_version
117+
env:
118+
FILE_NAME: ${{ steps.source.outputs.FILE }}
119+
# yamllint disable-line rule:line-length
120+
run: echo "VERSION=$(php "$FILE_NAME" --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+(\.[0-9]+)+')" >> "$GITHUB_OUTPUT"
121+
122+
- name: "DEBUG: Show grabbed version"
123+
run: echo ${{ steps.asset_version.outputs.VERSION }}
124+
125+
- name: Fail the build if the PHAR is not the correct version
126+
if: ${{ steps.asset_version.outputs.VERSION != steps.version.outputs.TAG }}
127+
run: exit 1
128+
129+
# #########################################
130+
# Verify install via PHIVE.
131+
# #########################################
132+
verify-phive:
133+
runs-on: ubuntu-latest
134+
135+
# Only run this workflow in the context of this repo.
136+
if: github.repository_owner == 'PHPCSStandards'
137+
138+
strategy:
139+
fail-fast: false
140+
matrix:
141+
pharfile:
142+
- 'phpcs'
143+
- 'phpcbf'
144+
145+
name: "PHIVE: ${{ matrix.pharfile }}"
146+
147+
steps:
148+
- name: Retrieve latest release info
149+
uses: octokit/[email protected]
150+
id: get_latest_release
151+
with:
152+
route: GET /repos/PHPCSStandards/PHP_CodeSniffer/releases/latest
153+
env:
154+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
155+
156+
- name: "DEBUG: Show API request failure status"
157+
if: ${{ failure() }}
158+
run: "echo No release found. Request failed with status ${{ steps.get_latest_release.outputs.status }}"
159+
160+
- name: Grab latest tag name from API response
161+
id: version
162+
run: |
163+
echo "TAG=${{ fromJson(steps.get_latest_release.outputs.data).tag_name }}" >> "$GITHUB_OUTPUT"
164+
165+
- name: "DEBUG: Show tag name found in API response"
166+
run: "echo ${{ steps.version.outputs.TAG }}"
167+
168+
- name: Setup PHP
169+
uses: shivammathur/setup-php@v2
170+
with:
171+
php-version: 'latest'
172+
ini-values: error_reporting=-1, display_errors=On
173+
coverage: none
174+
tools: phive
175+
176+
- name: Install
177+
run: phive install ${{ matrix.pharfile }} --copy --trust-gpg-keys 689DAD778FF08760E046228BA978220305CD5C32
178+
179+
- name: "DEBUG: List files"
180+
run: ls -R
181+
182+
- name: Verify attestation of the PHAR file
183+
run: gh attestation verify ./tools/${{ matrix.pharfile }} -o PHPCSStandards
184+
env:
185+
GH_TOKEN: ${{ github.token }}
186+
187+
# Note: the `.` is in the command to make it work for both PHPCS as well PHPCBF.
188+
- name: Verify the PHAR is nominally functional
189+
run: php ./tools/${{ matrix.pharfile }} . -e --standard=PSR12
190+
191+
- name: Grab the version
192+
id: asset_version
193+
env:
194+
FILE_NAME: ./tools/${{ matrix.pharfile }}
195+
# yamllint disable-line rule:line-length
196+
run: echo "VERSION=$(php "$FILE_NAME" --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+(\.[0-9]+)+')" >> "$GITHUB_OUTPUT"
197+
198+
- name: "DEBUG: Show grabbed version"
199+
run: echo ${{ steps.asset_version.outputs.VERSION }}
200+
201+
- name: Fail the build if the PHAR is not the correct version
202+
if: ${{ steps.asset_version.outputs.VERSION != steps.version.outputs.TAG }}
203+
run: exit 1

.remarkrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
{
1414
"skipUrlPatterns": [
1515
"^https?://github\\.com/PHPCSStandards/PHP_CodeSniffer/compare/[0-9\\.]+?\\.{3}[0-9\\.]+",
16-
"^https?://github\\.com/[A-Za-z0-9-]+"
16+
"^https?://github\\.com/[A-Za-z0-9-]+",
17+
"^https?://x\\.com/PHP_CodeSniffer"
1718
]
1819
}
1920
],

0 commit comments

Comments
 (0)