-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New release workflow triggered by the merge of a PR changing
IS_DEVELOPMENT_BUILD to false This is more streamlined than the previous approach, and works better for a world where 1 person isn't doing all the work. Now, the flow is simpler: - Do changes (e.g. protocol update), changelog & set IS_DEVELOPMENT_BUILD to false all in a single PR, which can be squash-merged if desired - Once the PR is merged, a draft release will be prepared - RestrictedActions will automatically set IS_DEVELOPMENT_BUILD back to true and bump the version - Tag will be created when the release is published Previously, multiple PRs might be needed, and the PR containing the release changelog couldn't be squash-merged. Manual intervention was also required to create a tag and prepare a release. This PR also includes new CI checks to check for basic errors like forgotten changelog files to ensure changelog links work correctly. Note: Only PRs from PMMP Team members with **write** access to the repository can trigger release generation. Random people cannot trigger release generation by sending PRs.
- Loading branch information
Showing
7 changed files
with
321 additions
and
24 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
name: Draft release from PR | ||
|
||
on: | ||
#presume that pull_request_target is safe at this point, since the PR was approved and merged | ||
#we need write access to prepare the release & create comments | ||
pull_request_target: | ||
types: | ||
- closed | ||
branches: | ||
- stable | ||
- minor-next | ||
- major-next | ||
- "legacy/*" | ||
paths: | ||
- "src/VersionInfo.php" | ||
|
||
jobs: | ||
check: | ||
name: Check release | ||
uses: ./.github/workflows/draft-release-pr-check.yml | ||
|
||
draft: | ||
name: Create GitHub draft release | ||
needs: [check] | ||
if: needs.check.outputs.valid == 'true' | ||
|
||
uses: ./.github/workflows/draft-release.yml | ||
|
||
post-draft-url-comment: | ||
name: Post draft release URL as comment | ||
needs: [draft] | ||
|
||
runs-on: ubuntu-20.04 | ||
|
||
steps: | ||
- name: Post draft release URL on PR | ||
uses: thollander/actions-comment-pull-request@v2 | ||
with: | ||
message: "[Draft release ${{ needs.draft.outputs.version }}](${{ needs.draft.outputs.draft-url }}) has been created for commit ${{ github.sha }}. Please review and publish it." | ||
|
||
trigger-post-release-workflow: | ||
name: Trigger post-release RestrictedActions workflow | ||
# Not sure if needs is actually needed here | ||
needs: [check] | ||
if: needs.check.outputs.valid == 'true' | ||
|
||
runs-on: ubuntu-20.04 | ||
|
||
steps: | ||
- name: Generate access token | ||
id: generate-token | ||
uses: actions/create-github-app-token@v1 | ||
with: | ||
app-id: ${{ vars.RESTRICTED_ACTIONS_DISPATCH_ID }} | ||
private-key: ${{ secrets.RESTRICTED_ACTIONS_DISPATCH_KEY }} | ||
owner: ${{ github.repository_owner }} | ||
repositories: RestrictedActions | ||
|
||
- name: Dispatch post-release restricted action | ||
uses: peter-evans/repository-dispatch@v3 | ||
with: | ||
token: ${{ steps.generate-token.outputs.token }} | ||
repository: ${{ github.repository_owner }}/RestrictedActions | ||
event-type: pocketmine_mp_post_release | ||
client-payload: '{"branch": "${{ github.ref }}"}' |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#Allows creating a release by pushing a tag | ||
#This might be useful for retroactive releases | ||
name: Draft release from git tag | ||
|
||
on: | ||
push: | ||
tags: "*" | ||
|
||
jobs: | ||
draft: | ||
name: Create GitHub draft release | ||
if: "startsWith(github.event.head_commit.message, 'Release ')" | ||
uses: ./.github/workflows/draft-release.yml |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
name: Release PR checks | ||
|
||
on: | ||
#do checks on every PR update | ||
pull_request: | ||
branches: | ||
- stable | ||
- minor-next | ||
- major-next | ||
- "legacy/*" | ||
paths: | ||
- "src/VersionInfo.php" | ||
|
||
#allow this workflow to be invoked on PR merge, prior to creating the release | ||
workflow_call: | ||
outputs: | ||
valid: | ||
description: Whether this commit is valid for release | ||
value: ${{ jobs.check-intent.outputs.valid && jobs.check-validity.result == 'success' }} | ||
|
||
permissions: | ||
contents: read #for user access check | ||
|
||
jobs: | ||
check-intent: | ||
name: Check release trigger | ||
runs-on: ubuntu-20.04 | ||
|
||
outputs: | ||
valid: ${{ steps.validate.outputs.DEV_BUILD == 'false' }} | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Check IS_DEVELOPMENT_BUILD flag | ||
id: validate | ||
run: | | ||
echo DEV_BUILD=$(sed -n "s/^\s*public const IS_DEVELOPMENT_BUILD = \(true\|false\);$/\1/p" src/VersionInfo.php) >> $GITHUB_OUTPUT | ||
check-validity: | ||
name: Validate release info | ||
needs: [check-intent] | ||
#don't do these checks if this isn't a release - we don't want to generate unnecessary failed statuses | ||
if: needs.check-intent.outputs.valid == 'true' | ||
|
||
runs-on: ubuntu-20.04 | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Setup PHP | ||
uses: shivammathur/setup-php@2.31.1 | ||
with: | ||
php-version: 8.2 | ||
|
||
- name: Restore Composer package cache | ||
uses: actions/cache@v4 | ||
with: | ||
path: | | ||
~/.cache/composer/files | ||
~/.cache/composer/vcs | ||
key: "composer-v2-cache-${{ hashFiles('./composer.lock') }}" | ||
restore-keys: | | ||
composer-v2-cache- | ||
- name: Install Composer dependencies | ||
run: composer install --no-dev --prefer-dist --no-interaction --ignore-platform-reqs | ||
|
||
- name: Check author permissions | ||
id: check-permission | ||
uses: actions-cool/check-user-permission@v2 | ||
with: | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
require: write | ||
username: ${{ github.event.pull_request.user.login }} | ||
#technically this would be fine for dependabot but generally bots don't count as team members | ||
check-bot: true | ||
|
||
- name: Abort if user permissions are insufficient | ||
#user doesn't have permission or is a bot | ||
if: steps.check-permission.outputs.require-result != 'true' || steps.check-permission.outputs.check-result != 'false' | ||
run: | | ||
echo "::error::This user is not authorized to trigger releases" | ||
exit 1 | ||
- name: Check changelog file is present | ||
id: file-presence | ||
run: | | ||
CHANGELOG_FILE="changelogs/$(php build/dump-version-info.php changelog_file_name)" | ||
if [ ! -f "${{ github.workspace }}/$CHANGELOG_FILE" ]; then | ||
echo "::error::$CHANGELOG_FILE does not exist" | ||
exit 1 | ||
fi | ||
echo FILE="$CHANGELOG_FILE" >> $GITHUB_OUTPUT | ||
- name: Check header is present in changelog file | ||
run: | | ||
FILE="${{ steps.file-presence.outputs.FILE }}" | ||
VERSION="$(php build/dump-version-info.php base_version)" | ||
if ! grep -Fqx "# $VERSION" "${{ github.workspace }}/$FILE"; then | ||
echo "::error::Header for $VERSION not found in $FILE" | ||
exit 1 | ||
fi | ||
- name: Check version is valid for the selected channel | ||
run: | | ||
CHANNEL="$(php build/dump-version-info.php channel)" | ||
if [ "$(php build/dump-version-info.php suffix_valid)" != "true" ]; then | ||
echo "::error::Version $(php build/dump-version-info.php base_version) is not allowed on the $CHANNEL channel" | ||
exit 1 | ||
fi |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
|
||
/* | ||
* | ||
* ____ _ _ __ __ _ __ __ ____ | ||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \ | ||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) | | ||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/ | ||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_| | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* @author PocketMine Team | ||
* @link http://www.pocketmine.net/ | ||
* | ||
* | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
use pocketmine\network\mcpe\protocol\ProtocolInfo; | ||
use pocketmine\VersionInfo; | ||
|
||
require dirname(__DIR__) . '/vendor/autoload.php'; | ||
|
||
/* | ||
* Dumps version info in a machine-readable format for use in GitHub Actions workflows | ||
*/ | ||
|
||
/** | ||
* @var string[]|\Closure[] $options | ||
* @phpstan-var array<string, string|\Closure() : string> $options | ||
*/ | ||
$options = [ | ||
"base_version" => VersionInfo::BASE_VERSION, | ||
"mcpe_version" => ProtocolInfo::MINECRAFT_VERSION_NETWORK, | ||
"is_dev" => VersionInfo::IS_DEVELOPMENT_BUILD, | ||
"changelog_file_name" => function() : string{ | ||
$version = VersionInfo::VERSION(); | ||
$result = $version->getMajor() . "." . $version->getMinor(); | ||
$suffix = $version->getSuffix(); | ||
if($suffix !== ""){ | ||
if(preg_match('/^([A-Za-z]+)(\d+)$/', $suffix, $matches) !== 1){ | ||
fwrite(STDERR, "error: invalid current version suffix \"$suffix\"; aborting" . PHP_EOL); | ||
exit(1); | ||
} | ||
$baseSuffix = $matches[1]; | ||
$result .= "-" . strtolower($baseSuffix); | ||
} | ||
return $result . ".md"; | ||
}, | ||
"changelog_md_header" => fn() : string => str_replace(".", "", VersionInfo::BASE_VERSION), | ||
"prerelease" => fn() : bool => VersionInfo::VERSION()->getSuffix() !== "", | ||
"channel" => VersionInfo::BUILD_CHANNEL, | ||
"suffix_valid" => function() : bool{ | ||
//TODO: maybe this should be put into its own script? | ||
$suffix = VersionInfo::VERSION()->getSuffix(); | ||
if(VersionInfo::BUILD_CHANNEL === "stable"){ | ||
//stable builds may not have suffixes | ||
return $suffix === ""; | ||
} | ||
if(VersionInfo::BUILD_CHANNEL === "alpha" || VersionInfo::BUILD_CHANNEL === "beta"){ | ||
$upperChannel = strtoupper(VersionInfo::BUILD_CHANNEL); | ||
$upperSuffix = strtoupper($suffix); | ||
return str_starts_with($upperSuffix, $upperChannel) && is_numeric(substr($upperSuffix, strlen($upperChannel))); | ||
} | ||
return true; | ||
} | ||
]; | ||
if(count($argv) !== 2 || !isset($options[$argv[1]])){ | ||
fwrite(STDERR, "Please provide an option (one of: " . implode(", ", array_keys($options)) . PHP_EOL); | ||
exit(1); | ||
} | ||
|
||
$result = $options[$argv[1]]; | ||
if($result instanceof Closure){ | ||
$result = $result(); | ||
} | ||
if(is_bool($result)){ | ||
echo $result ? "true" : "false"; | ||
}else{ | ||
echo $result; | ||
} |
Oops, something went wrong.