From 60d0f5403c7b7fd00b068e8ede3326a3b566bcdd Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Tue, 8 Mar 2022 20:13:42 +0100 Subject: [PATCH] CI: Use build script to publish new releases Since Pico depends on PicoDeprecated, and PicoDeprecated depends on Pico, a chicken-egg-problem arises: When pushing a new tag for Pico, GitHub Actions will try to build this new release by downloading the matching version of PicoDeprecated from Packagist. Since we didn't release a new version of PicoDeprecated yet, this will fail. So we need to push PicoDeprecated's tag first. Doing so yields GitHub Actions trying to build PicoDeprecated's new release - by trying to download the matching version of Pico from Packagist, which doesn't exist yet. Thus builds will always fail - unless you push both tags at the exact same time, and unless you send some prayers that GitHub Actions delays building until Packagist picks up the new releases. The simplest solution is not to use GitHub Actions to publish new releases, but letting the user to do it instead. With this changeset this is as simple as `make publish version=v3.0.0`. The 'deploy-release' GitHub workflow now just updates the website and is triggered by publishing the GitHub release, not the tag. This additionally allows the user to perform some manual tests before publication. The build script now depends on GitHub CLI (`gh`), see https://cli.github.com/. You must setup authentication first (`gh auth login`). --- .build/build.sh | 42 +++++++++++++- .github/workflows/deploy-branch.yml | 4 -- .github/workflows/deploy-release.yml | 86 +--------------------------- .github/workflows/test.yml | 6 +- Makefile | 8 ++- 5 files changed, 54 insertions(+), 92 deletions(-) diff --git a/.build/build.sh b/.build/build.sh index b05846c..02693b3 100755 --- a/.build/build.sh +++ b/.build/build.sh @@ -32,6 +32,9 @@ elif ! which "$COMPOSER" > /dev/null; then elif ! which "git" > /dev/null; then echo "Missing script dependency: git" >&2 exit 1 +elif ! which "gh" > /dev/null; then + echo "Missing script dependency: gh" >&2 + exit 1 elif ! which "rsync" > /dev/null; then echo "Missing script dependency: rsync" >&2 exit 1 @@ -57,8 +60,11 @@ PICO_DEPRECATED_NAME="pico-deprecated" PICO_DEPRECATED_PROJECT="picocms/pico-deprecated" PICO_DEPRECATED_DIR= +PHP_VERSION="7.2" + # options VERSION= +PUBLISH= NOCHECK= NOCLEAN= @@ -73,6 +79,7 @@ while [ $# -gt 0 ]; do echo " --help display this help and exit" echo echo "Application options:" + echo " --publish create GitHub release and upload artifacts" echo " --pico-composer PATH path to a local copy of '$PICO_COMPOSER_PROJECT'" echo " --pico-theme PATH path to a local copy of '$PICO_THEME_PROJECT'" echo " --pico-deprecated PATH path to a local copy of '$PICO_DEPRECATED_PROJECT'" @@ -83,6 +90,9 @@ while [ $# -gt 0 ]; do echo "that this script will perform a large number of strict sanity checks before" echo "building a new non-development version of Pico. VERSION must start with 'v'." exit 0 + elif [ "$1" == "--publish" ]; then + PUBLISH="y" + shift elif [ "$1" == "--no-check" ]; then NOCHECK="y" shift @@ -223,6 +233,7 @@ if [ "$VERSION_STABILITY" != "dev" ]; then GIT_LOCAL_TAG="$(git rev-parse --verify "refs/tags/$VERSION" 2> /dev/null || true)" GIT_REMOTE="$(git 'for-each-ref' --format='%(upstream:remotename)' "$(git symbolic-ref -q HEAD)")" GIT_REMOTE_TAG="$(git ls-remote "${GIT_REMOTE:-origin}" "refs/tags/$VERSION" 2> /dev/null | cut -f 1 || true)" + PHP_VERSION_LOCAL="$("$PHP" -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')" if [ "$VERSION" != "$BUILD_VERSION" ]; then echo "Unable to build Pico: Building $VERSION, but Pico indicates $BUILD_VERSION" >&2 @@ -242,14 +253,20 @@ if [ "$VERSION_STABILITY" != "dev" ]; then elif [ "$GIT_LOCAL_TAG" != "$GIT_REMOTE_TAG" ]; then echo "Unable to build Pico: Building $VERSION, but the matching local and remote Git tags differ" >&2 exit 1 + elif [ "$PHP_VERSION_LOCAL" != "$PHP_VERSION" ]; then + echo "Unable to build Pico: Refusing to build Pico with PHP $PHP_VERSION_LOCAL, expecting PHP $PHP_VERSION" >&2 + exit 1 elif [ -n "$PICO_COMPOSER_DIR" ] || [ -n "$PICO_THEME_DIR" ] || [ -n "$PICO_DEPRECATED_DIR" ]; then echo "Unable to build Pico: Refusing to build a non-dev version with local dependencies" >&2 exit 1 fi -elif [ -z "$NOCHECK" ]; then - if [[ "$VERSION" != "$BUILD_VERSION"* ]]; then +else + if [ -z "$NOCHECK" ] && [[ "$VERSION" != "$BUILD_VERSION"* ]]; then echo "Unable to build Pico: Building $VERSION, but Pico indicates $BUILD_VERSION" >&2 exit 1 + elif [ -n "$PUBLISH" ]; then + echo "Unable to build Pico: Refusing to publish a dev version" >&2 + exit 1 fi fi @@ -446,3 +463,24 @@ find . -mindepth 1 -maxdepth 1 -printf '%f\0' \ echo "Creating release archive '$ARCHIVE_FILENAME.zip'..." zip -q -r "$APP_DIR/$ARCHIVE_FILENAME.zip" . + +echo + +# publish release +if [ -n "$PUBLISH" ]; then + # switch to app dir + cd "$APP_DIR" + + # create GitHub release and upload release archives + echo "Creating GitHub release and uploading release archives..." + + GITHUB_PRERELEASE= + [ "$VERSION_STABILITY" == "stable" ] || GITHUB_PRERELEASE="--prerelease" + + gh release create "$VERSION" \ + --title "Version $VERSION_FULL" \ + --generate-notes \ + "$GITHUB_PRERELEASE" \ + "$APP_DIR/$ARCHIVE_FILENAME.tar.gz" \ + "$APP_DIR/$ARCHIVE_FILENAME.zip" +fi diff --git a/.github/workflows/deploy-branch.yml b/.github/workflows/deploy-branch.yml index a6ee7ad..c8fd01b 100644 --- a/.github/workflows/deploy-branch.yml +++ b/.github/workflows/deploy-branch.yml @@ -12,10 +12,6 @@ env: CI_TOOLS_SETUP: https://raw.githubusercontent.com/picocms/ci-tools/master/setup.sh jobs: - test: - name: Test Pico CMS - uses: ./.github/workflows/test.yml - website: name: Update website for branch updates diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index 1109cd4..96360b8 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -1,8 +1,8 @@ -name: Git tag deployment +name: Git release deployment on: - push: - tags: [ 'v*.*.*' ] + release: + types: [ 'published' ] env: WEBSITE_REPO_SLUG: picocms/picocms.github.io @@ -10,10 +10,6 @@ env: CI_TOOLS_SETUP: https://raw.githubusercontent.com/picocms/ci-tools/master/setup.sh jobs: - test: - name: Test Pico CMS - uses: ./.github/workflows/test.yml - website: name: Update website for new releases @@ -21,8 +17,6 @@ jobs: permissions: contents: write - needs: test - env: PHP_VERSION: '7.4' BUILD_DIR: ./build @@ -176,77 +170,3 @@ jobs: commit_user_email: bot@picocms.org commit_message: >- Update cloc statistics for ${{ github.ref_name }} - - deploy: - name: Create Pico release - - runs-on: ubuntu-latest - permissions: - contents: write - - needs: test - - env: - PHP_VERSION: '7.2' - - steps: - - name: Setup CI tools - run: | - . <(curl -fsS -L "$CI_TOOLS_SETUP") - echo "CI_TOOLS_PATH=$CI_TOOLS_PATH" | tee -a "$GITHUB_ENV" - - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Setup PHP ${{ env.PHP_VERSION }} - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ env.PHP_VERSION }} - tools: composer - - - name: Setup Composer auth - run: | - composer config --global github-oauth.github.com "${{ github.token }}" - - - name: Get Composer cache directory - run: | - COMPOSER_CACHE_DIR="$(composer config --global cache-dir)" - echo "COMPOSER_CACHE_DIR=$COMPOSER_CACHE_DIR" | tee -a "$GITHUB_ENV" - - - name: Restore Composer cache - uses: actions/cache@v2 - with: - path: ${{ env.COMPOSER_CACHE_DIR }} - key: ${{ runner.os }}-composer-php${{ env.PHP_VERSION }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Parse Pico version - run: | - . "$CI_TOOLS_PATH/parse_version.inc.sh" - - if ! parse_version "$GITHUB_REF_NAME"; then - echo "Invalid version string: $GITHUB_REF_NAME" >&2 - exit 1 - fi - - printf '%s=%s\n' \ - "PICO_VERSION_FULL" "$VERSION_FULL" \ - "PICO_VERSION_STABILITY" "$VERSION_STABILITY" \ - | tee -a "$GITHUB_ENV" - - - name: Build Pico and create release archives - run: | - make build version="$GITHUB_REF_NAME" - - - name: Create GitHub release and upload release archives - uses: softprops/action-gh-release@v1 - with: - name: Version ${{ env.PICO_VERSION_FULL }} - body: >- - Pico ${{ github.ref_name }} - prerelease: ${{ env.PICO_VERSION_STABILITY != 'stable' }} - draft: true - files: | - pico-release-${{ github.ref_name }}.tar.gz - pico-release-${{ github.ref_name }}.zip diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d618b02..bddc9a9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,8 +1,12 @@ name: Test Pico CMS on: + push: + branches: + - 'master' + - 'pico-3.0' + tags: [ 'v*.*.*' ] pull_request: {} - workflow_call: {} jobs: test: diff --git a/Makefile b/Makefile index a8335c9..3d4bd55 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ version?= nocheck?=false +publish=false php?=php composer?=composer @@ -37,15 +38,18 @@ clean-export: build: export PHP=$(php) build: export COMPOSER=$(composer) build: - ./.build/build.sh$(if $(filter true,$(nocheck)), --no-check,)$(if $(version), "$(version)",) + ./.build/build.sh$(if $(filter true,$(publish)), --publish,)$(if $(filter true,$(nocheck)), --no-check,)$(if $(version), "$(version)",) export: git archive --prefix "$(app_name)/" -o "./$(export)" HEAD +publish: publish=true +publish: build + composer: $(composer) install --optimize-autoloader --no-dev .PHONY: all \ clean clean-build clean-export \ - build export \ + build export publish \ composer