From 9b5c5921dc8167b9f36ede880550c57b0fe7e33b Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 30 Aug 2023 16:01:29 +0100 Subject: [PATCH 1/4] Revert "chore: update release workflow to use new versioning scheme" This reverts commit e2736e6bbfafceb94aa105c11dd249ddb77e83e0. --- .github/workflows/manual_release_package.yml | 38 ++++++++++++++ .github/workflows/release_image.yml | 23 ++------ .../workflows/update-and-prepare-release.yml | 52 +++++++++++++++++++ .github/workflows/update-gems.yml | 41 +++++++++++++++ README.md | 26 +--------- RELEASING.md | 37 +------------ script/release-workflow/docker-push.sh | 41 ++++++--------- script/release-workflow/next-docker-tag.sh | 21 ++++++++ script/release-workflow/prepare-release.sh | 15 ------ script/release-workflow/set-env-vars.sh | 32 ++++-------- script/test.sh | 1 + script/update-gems-workflow/detect-changes.sh | 8 --- .../git-commit-and-push-gemfile.sh | 22 -------- script/update-gems-workflow/update-gems.sh | 25 --------- script/workflows/prepare-release.sh | 13 +++++ script/workflows/update.sh | 24 +++++++++ 16 files changed, 221 insertions(+), 198 deletions(-) create mode 100644 .github/workflows/manual_release_package.yml create mode 100644 .github/workflows/update-and-prepare-release.yml create mode 100644 .github/workflows/update-gems.yml create mode 100755 script/release-workflow/next-docker-tag.sh delete mode 100755 script/update-gems-workflow/detect-changes.sh delete mode 100755 script/update-gems-workflow/git-commit-and-push-gemfile.sh delete mode 100755 script/update-gems-workflow/update-gems.sh create mode 100755 script/workflows/prepare-release.sh create mode 100755 script/workflows/update.sh diff --git a/.github/workflows/manual_release_package.yml b/.github/workflows/manual_release_package.yml new file mode 100644 index 0000000..9fa0f92 --- /dev/null +++ b/.github/workflows/manual_release_package.yml @@ -0,0 +1,38 @@ +name: Release Docker image with updated packaging + +on: + workflow_dispatch: + inputs: + release: + description: Release number + required: true + type: number + +jobs: + release: + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: ruby/setup-ruby@v1 + + - name: Prepare release + id: prepare-release + run: script/workflows/prepare-release.sh + env: + RELEASE: ${{ inputs.release }} + + - name: Commit and push version and changelog + uses: EndBug/add-and-commit@v4 + with: + add: CHANGELOG.md + author_name: Beth Skurrie via Github Action + author_email: beth@bethesque.com + message: 'chore(release): version ${{ steps.prepare-release.outputs.tag }}' + tag: '${{ steps.prepare-release.outputs.tag }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release_image.yml b/.github/workflows/release_image.yml index 16ab579..155b2a5 100644 --- a/.github/workflows/release_image.yml +++ b/.github/workflows/release_image.yml @@ -15,20 +15,7 @@ on: - major - minor - patch - # Sets the first part of the Docker tag - this will update the VERSION file - version: - description: "Custom version, requires increment to be set" - required: false - tag: - description: "Custom Docker image tag (note - this won't update the VERSION file and is for non-prod releases only)" - required: false - push_to_latest: - description: 'Should push to latest' - type: boolean - default: true - docker_repository: - description: The Docker repository to which the image should be published - default: pactfoundation + jobs: release: runs-on: ubuntu-latest @@ -48,9 +35,5 @@ jobs: env: DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} - DOCKER_REPOSITORY: ${{ github.event.inputs.docker_repository }} - TAG: ${{ github.event.inputs.tag }} - VERSION: ${{ github.event.inputs.version }} - # populate INCREMENT from workflow_dispatch or repository_dispatch - INCREMENT: ${{ github.event.client_payload.increment }}${{ github.event.inputs.increment }} - PUSH_TO_LATEST: ${{ github.event.inputs.push_to_latest }} + CUSTOM_TAG: ${{ github.event.client_payload.tag }} + INCREMENT: ${{ github.event.inputs.increment }} diff --git a/.github/workflows/update-and-prepare-release.yml b/.github/workflows/update-and-prepare-release.yml new file mode 100644 index 0000000..c4f568f --- /dev/null +++ b/.github/workflows/update-and-prepare-release.yml @@ -0,0 +1,52 @@ +# TODO abort if there are no changes to the Gemfile. + +name: Update gems and prepare to release Docker image + +on: + repository_dispatch: + types: + - gem-released-disabled + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: ruby/setup-ruby@v1 + + - id: update + run: script/workflows/update.sh + env: + RELEASED_GEM_NAME: ${{ github.event.client_payload.name }} + RELEASED_GEM_VERSION: ${{ github.event.client_payload.version }} + + - name: Commit and push gem file changes + uses: EndBug/add-and-commit@v4 + with: + add: Gemfile.lock + author_name: Beth Skurrie via Github Action + author_email: beth@bethesque.com + message: 'feat(gems): ${{ steps.update.outputs.commit_message }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - id: prepare-release + name: Update version and generate changelog + run: script/workflows/prepare-release.sh + env: + INCREMENT: ${{ github.event.client_payload.increment }} + + - name: Commit and push version and changelog + uses: EndBug/add-and-commit@v4 + with: + add: lib/pact/cli/version.rb Gemfile.lock CHANGELOG.md + author_name: Beth Skurrie via Github Action + author_email: beth@bethesque.com + message: 'chore(release): version ${{ steps.prepare-release.outputs.tag }}' + tag: '${{ steps.prepare-release.outputs.tag }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-gems.yml b/.github/workflows/update-gems.yml new file mode 100644 index 0000000..b721523 --- /dev/null +++ b/.github/workflows/update-gems.yml @@ -0,0 +1,41 @@ +# TODO abort if there are no changes to the Gemfile. + +name: Update gems + +on: + repository_dispatch: + types: + - gem-released + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: ruby/setup-ruby@v1 + + - id: update + run: script/workflows/update.sh + env: + RELEASED_GEM_NAME: ${{ github.event.client_payload.name }} + RELEASED_GEM_VERSION: ${{ github.event.client_payload.version }} + + - name: Commit and push gem file changes + uses: EndBug/add-and-commit@v4 + with: + add: Gemfile.lock + author_name: Beth Skurrie via Github Action + author_email: beth@bethesque.com + message: 'feat(gems): ${{ steps.update.outputs.commit_message }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Trigger release + uses: peter-evans/repository-dispatch@v1 + with: + token: ${{ secrets.GHTOKENFORPACTCLIRELEASE }} + event-type: release-triggered diff --git a/README.md b/README.md index a644c09..17462ab 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Pact CLI -This tool provides an amalgamated CLI of all the Pact CLI tools available in the Pact Ruby implementation (publish and verify pacts, and interact with the Pact Broker). While it is functionally the same as the [pact-ruby-standalone](https://github.com/pact-foundation/pact-ruby-standalone) it is packaged as a Docker container and a single top level entrypoint (`pact`). You can pull the `pactfoundation/pact-cli` image from [Dockerhub](https://hub.docker.com/r/pactfoundation/pact-cli) - -> Note: On 23rd May 2023, the format of the docker tag changed from ending with the Pact Cli Gem version (`0.51.0.4`), where `.4` noted a change to the one of the packaged gems, to ending with the Pact Cli gem version (`0.52.0-pactcli0.52.0`). Read about the new versioning scheme [here](#versioning). +This tool provides an amalgamated CLI of all the Pact CLI tools available in the Pact Ruby implementation (publish and verify pacts, and interact with the Pact Broker). While it is functionally the same as the [pact-ruby-standalone](https://github.com/pact-foundation/pact-ruby-standalone) it is packaged as a Docker container and a single top level entrypoint (`pact`). [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/pact-foundation/pact-msw-adapter/graphs/commit-activity) @@ -218,28 +216,6 @@ lib pact-cli.gemspec ``` -## Versioning - -The Docker image tag uses a semantic-like versioning scheme (Docker tags don't support the `+` symbol, so we cannot implement a strict semantic version). The format of the tag is `M.m.p-pactcli` eg. `0.52.0-pactcli0.52.0`. The `M.m.p` (eg. `0.52.0`) is the semantic part of the tag number, while the `-pactcli` suffix is purely informational. - -The major version will be bumped for: - - * Major increments of the Pact Cli gem - * Major increments of the base image that contain backwards incompatible changes (eg. dropping support for Docker 19) - * Any other backwards incompatible changes made for any reason (eg. environment variable mappings, entrypoints, tasks, supported auth) - -The minor version will be bumped for: - - * Minor increments of the Pact Cli gem - * Additional non-breaking functionality added to the Docker image - -The patch version will be bumped for: - - * Patch increments of the Pact Cli gem - * Other fixes to the Docker image - -Until May 2023, the versioning scheme used the `M.m.p` from the Pact Cli gem, with an additional `RELEASE` number at the end (eg. `0.51.0.4`). This scheme was replace by the current scheme because it was unable to semantically convey changes made to the Docker image that were unrelated to a Pact Cli gem version change (eg. alpine upgrades). - ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/pact-foundation/pact-ruby-cli. diff --git a/RELEASING.md b/RELEASING.md index 47a8c44..c726297 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,40 +1,5 @@ # Releasing -When one of the Pact gems is released, it sends a repository dispatch notification with event type `gem-released`, which triggers the `Update gems` Github Action that updates the gems and commits the changes. The `Release` workflow is then triggered by another repository dispatch action of type `release-triggered` which generates the release notes, builds and publishes the Docker image, and creates the git commits and tags. +Manual releases are not generally necessary. When one of the Pact gems is released, it sends a repository dispatch notification with event type `gem-released`, which triggers the `Update gems` Github Action that updates the gems and commits the changes. The `Release` workflow is then triggered by another repository dispatch action of type `release-triggered` which generates the release notes, builds and publishes the Docker image, and creates the git commits and tags. If the packaging code needs to be updated, a manual release can be performed by running the `Release Docker image with updated packaging` workflow from the UI. - -# Releasing - -Please read the [versioning](/#versioning) section of the README file before continuing. - -The semantic version part of the tag is stored in the `VERSION` file at the root of the repository. - -> Manual releases are not generally necessary. - -## Automatic releases of the Docker image triggered by the release of one of the Pact gem - -When one of the Pact gems is released by the Github Action in its repository, the `repository_dispatch` action of the `pact-ruby-cli` repository will be invoked with the type `gem-released`, and the release details (name, version, increment). - -This causes the `update_gems.yml` workflow to be run. At the end of the workflow, it will trigger a release by invoking the `repository_dispatch` action with type `release-triggered`, passing in the increment. - -Note: sometimes bundler cannot find the newly released gem straight away, and the job needs to be re-run via the UI. - -### Manual releases of the Docker image triggered by the release of one of the Pact gem - -* On the Github Actions page, select `Update gems` -* Select `Run workflow` -* To attempt to update a particular gem - update the default `released_gem_name` & set the required `released_gem_version` and then click `Run workflow`. This should be the normal process if a Pact gem has been updated. -* To release a non-minor version change, select the `released_gem_version_increment` you want along with the above values, and click `Run workflow`. -* If the `Gemfile.lock` is updated, the results will be committed back to the repository, along with an updated `lib/pact/cli/version.rb` set to the `released_gem_version_increment` (which defaults to minor) -* This will trigger an automated release of the Docker image, where the Docker semver tag will be updated by a the same `released_gem_version_increment` - - -## Manually releasing the Docker image - -* On the Github Actions page, select `Release Docker image` -* Select `Run workflow` -* To release a minor version change, do not set any inputs - just click `Run workflow`. This should be the normal process if you've done some changes to the Docker image. -* To release a non-minor version change, select the increment you want, and click `Run workflow`. -* To set a custom version number (not sure of the usecase for this, but just in case...), set both the version AND the increment and click `Run workflow`. -* To do a completely custom tag, just set the "Custom Docker image tag" and click `Run workflow`. If you do this, the VERSION file will NOT be updated. It is for testing purposes only. diff --git a/script/release-workflow/docker-push.sh b/script/release-workflow/docker-push.sh index fb0e31c..a1bd2dd 100755 --- a/script/release-workflow/docker-push.sh +++ b/script/release-workflow/docker-push.sh @@ -2,29 +2,22 @@ set -euo >/dev/null -## Publish a multi arch build with -multi added to the tag -## ($TAG||$MAJOR_TAG||$LATEST)-multi -push_multi() { - ## These will use cached builds, so wont build every time. - docker buildx build --platform=linux/amd64,linux/arm64,linux/arm \ - --output=type=image,push=true \ - -t ${DOCKER_IMAGE_ORG_AND_NAME}:$1-multi . -} -push() { - docker buildx build --platform=linux/amd64 \ - --output=type=image,push=true \ - -t ${DOCKER_IMAGE_ORG_AND_NAME}:$1 . -} - -if [ -n "${MAJOR_TAG:-}" ]; then - push ${MAJOR_TAG} - push_multi ${MAJOR_TAG} -fi +# Enable when we bump the major version to 1 (which we should) +# if [ -n "${MAJOR_TAG}" ]; then +# docker tag ${DOCKER_IMAGE_ORG_AND_NAME}:latest ${DOCKER_IMAGE_ORG_AND_NAME}:${MAJOR_TAG} +# docker push ${DOCKER_IMAGE_ORG_AND_NAME}:${MAJOR_TAG} +# docker push ${DOCKER_IMAGE_ORG_AND_NAME}:latest +# fi -push ${TAG} -push_multi ${TAG} -if [ "${PUSH_TO_LATEST}" != "false" ]; then - push latest - push_multi latest -fi \ No newline at end of file +docker buildx build --platform=linux/amd64 \ + --output=type=image,push=true \ + -t ${DOCKER_IMAGE_ORG_AND_NAME}:latest \ + -t ${DOCKER_IMAGE_ORG_AND_NAME}:${TAG} . + ## We will temporarily publish a multi manifest built as $TAG-multi + ## To avoid any issues with existing users. We can ask users for + ## Feedback and then promote to a multi-manifest build +docker buildx build --platform=linux/amd64,linux/arm64,linux/arm \ + --output=type=image,push=true \ + -t ${DOCKER_IMAGE_ORG_AND_NAME}:latest-multi \ + -t ${DOCKER_IMAGE_ORG_AND_NAME}:${TAG}-multi . \ No newline at end of file diff --git a/script/release-workflow/next-docker-tag.sh b/script/release-workflow/next-docker-tag.sh new file mode 100755 index 0000000..3c76a34 --- /dev/null +++ b/script/release-workflow/next-docker-tag.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +set -eu + +gem_version_from_gemfile_lock() { + grep "pact_broker (" pact_broker/Gemfile.lock | awk -F '[()]' '{print $2}' +} + +gem_version=$(ruby -I lib -e "require 'pact/cli/version.rb'; puts Pact::Cli::VERSION") +existing_tags=$(git tag) +existing_release_numbers_for_current_gem_version=$(echo "$existing_tags" | grep "${gem_version}\." | sed 's/'${gem_version}'\.//g' | grep -E "^[0-9]+$" | cat) + +if [ -n "${existing_release_numbers_for_current_gem_version}" ]; then + last_release_number=$(printf "0\n${existing_release_numbers_for_current_gem_version}" | sort -g | tail -1) + next_release_number=$(( $last_release_number + 1 )) +else + next_release_number=0 +fi + +tag="${gem_version}.${next_release_number}" +echo $tag diff --git a/script/release-workflow/prepare-release.sh b/script/release-workflow/prepare-release.sh index 31a37c5..387424b 100755 --- a/script/release-workflow/prepare-release.sh +++ b/script/release-workflow/prepare-release.sh @@ -1,22 +1,7 @@ #!/bin/sh set -euo >/dev/null -docker_compose_files=$(find . -name "docker-compose*.yml" -not -name "*test*") - -for file in $docker_compose_files; do - cat $file | sed -e "s~image: pactfoundation/pact-cli:.*~image: pactfoundation/pact-cli:${TAG}~g" > dc-tmp - mv dc-tmp $file -done bundle exec conventional-changelog version=${TAG} force=true - -if [ -n "$VERSION" ]; then - bundle exec bump set $VERSION --no-commit - git add VERSION -else - echo "Cannot update VERSION file as no VERSION has been specified" -fi - git add CHANGELOG.md -git add docker-compose* git commit -m "chore(release): version ${TAG}" diff --git a/script/release-workflow/set-env-vars.sh b/script/release-workflow/set-env-vars.sh index fd6b3dd..dae6688 100755 --- a/script/release-workflow/set-env-vars.sh +++ b/script/release-workflow/set-env-vars.sh @@ -12,27 +12,13 @@ else export ARCH=amd64 fi -if [ -z "$TAG" ]; then - if [ -n "$VERSION" ] && [ -z "$INCREMENT" ]; then - echo "If VERSION is specified, then INCREMENT must also be specified" - exit 1 - fi - - export INCREMENT=${INCREMENT:-minor} - - if [ -z "$VERSION" ]; then - export VERSION=$(bundle exec bump show-next $INCREMENT) - fi - - export PACT_CLI_VERSION=$(ruby -I lib -e "require 'pact/cli/version.rb'; puts Pact::Cli::VERSION") - export TAG="$VERSION-pactcli${PACT_CLI_VERSION}" - export MAJOR_TAG="$(echo $VERSION | cut -d'.' -f1)" - - echo "INCREMENT=$INCREMENT" - echo "VERSION=$VERSION" - echo "PACT_CLI_VERSION=$PACT_CLI_VERSION" - echo "TAG=$TAG" - echo "MAJOR_TAG=$MAJOR_TAG" +if [ -n "${CUSTOM_TAG:-}" ]; then + export TAG=$CUSTOM_TAG + export MAJOR_TAG="" else - echo "TAG=$TAG" -fi \ No newline at end of file + export TAG=$(script/release-workflow/next-docker-tag.sh) + export MAJOR_TAG=$(echo $TAG | cut -d'.' -f1) +fi + +echo "Set TAG=${TAG}" +echo "Set MAJOR_TAG=${MAJOR_TAG}" diff --git a/script/test.sh b/script/test.sh index 79b375b..781c6fd 100755 --- a/script/test.sh +++ b/script/test.sh @@ -2,6 +2,7 @@ docker build . -t pactfoundation/pact-cli docker run --rm pactfoundation/pact-cli:latest +docker run --rm pactfoundation/pact-cli:latest --help docker run --rm pactfoundation/pact-cli:latest mock-service --help docker run --rm pactfoundation/pact-cli:latest pact-broker --help docker run --rm pactfoundation/pact-cli:latest pactflow --help diff --git a/script/update-gems-workflow/detect-changes.sh b/script/update-gems-workflow/detect-changes.sh deleted file mode 100755 index b0615c1..0000000 --- a/script/update-gems-workflow/detect-changes.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ -z "$(git diff Gemfile.lock)" ] ; then - echo "No gems updated. Exiting." - exit 1 -else - echo "Gems updated, continuing with release." -fi diff --git a/script/update-gems-workflow/git-commit-and-push-gemfile.sh b/script/update-gems-workflow/git-commit-and-push-gemfile.sh deleted file mode 100755 index 9933fe0..0000000 --- a/script/update-gems-workflow/git-commit-and-push-gemfile.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -set -euo >/dev/null - -git add Gemfile.lock -git add lib/pact/cli/version.rb -PACT_CLI_VERSION=$(ruby -I lib -e "require 'pact/cli/version.rb'; puts Pact::Cli::VERSION") - -if [ -n "${RELEASED_GEM_NAME}" ] && [ -n "${RELEASED_GEM_VERSION}" ]; then - git commit -m "feat(gems): pact-cli v$PACT_CLI_VERSION: update ${RELEASED_GEM_NAME} gem to version ${RELEASED_GEM_VERSION} - -[ci-skip] -" -else - updated_gems=$(git diff --staged Gemfile.lock | grep '^+' | grep '(' | sed -e "s/+ *//" | paste -sd "," - | sed -e 's/,/, /g') - git commit -m "feat(gems): pact-cli v$PACT_CLI_VERSION: update to ${updated_gems} - -[ci-skip] -" -fi - -git push diff --git a/script/update-gems-workflow/update-gems.sh b/script/update-gems-workflow/update-gems.sh deleted file mode 100755 index a169d1d..0000000 --- a/script/update-gems-workflow/update-gems.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -set -euo >/dev/null - -## Update the version of the CLI in the Gemfile.lock and lib/pact/cli/version.rb -## bundle exec bump updates VERSION instead of pact/cli/version.rb -## so we store it, update our bundle, and then write it back -## the PACT_CLI_DOCKER_VERSION is our Docker semantic tag -PACT_CLI_DOCKER_VERSION=$(cat VERSION) -rm VERSION -BUMP_VERSION=$(cat Gemfile.lock | grep 'bump' -m 1 | sed 's/.*(\(.*\))/\1/') -gem install bump -v $BUMP_VERSION -bump ${RELEASED_GEM_INCREMENT:-minor} --no-commit - -if [ -n "${RELEASED_GEM_NAME:-}" ] && [ -n "${RELEASED_GEM_VERSION:-}" ]; then - gem install ${RELEASED_GEM_NAME} -v ${RELEASED_GEM_VERSION} - bundle update ${RELEASED_GEM_NAME} -else - bundle update -fi - -## Make sure we write our original PACT_CLI_DOCKER_VERSION back -echo $PACT_CLI_DOCKER_VERSION > VERSION -## we dont really need to do this, as we perform the following -# git add Gemfile.lock and lib/pact/cli/version.rb \ No newline at end of file diff --git a/script/workflows/prepare-release.sh b/script/workflows/prepare-release.sh new file mode 100755 index 0000000..5e92eb3 --- /dev/null +++ b/script/workflows/prepare-release.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e + +if [ -z "${RELEASE}" ]; then + bundle exec bump ${INCREMENT:-minor} --no-commit + export RELEASE=0 +fi + +export VERSION=$(ruby -I lib -e "require 'pact/cli/version.rb'; puts Pact::Cli::VERSION") +bundle exec rake generate_changelog +git diff CHANGELOG.md +echo "::set-output name=tag::${VERSION}.${RELEASE}" diff --git a/script/workflows/update.sh b/script/workflows/update.sh new file mode 100755 index 0000000..be51a23 --- /dev/null +++ b/script/workflows/update.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +set -e + +if [ -n "${RELEASED_GEM_NAME}" ] && [ -n "${RELEASED_GEM_VERSION}" ]; then + echo "Installing $RELEASED_GEM_NAME version $RELEASED_GEM_VERSION" + gem install $RELEASED_GEM_NAME -v $RELEASED_GEM_VERSION + bundle update $RELEASED_GEM_NAME + + if [ -z "$(git diff Gemfile.lock | grep + | grep " ${RELEASED_GEM_NAME} " || true)" ]; then + echo "Could not update $RELEASED_GEM_NAME to $RELEASED_GEM_VERSION. Exiting." + exit 1 + fi +fi + +bundle update + +if ! git diff-index --quiet HEAD Gemfile.lock; then + updated_gems=$(git diff Gemfile.lock | grep + | grep pact | sed -e "s/+ *//" | ruby -e 'puts ARGF.read.split("\n").join(", ")') + echo "::set-output name=commit_message::updated ${updated_gems}" +else + echo "No gems updated. Exiting." + exit 1 +fi \ No newline at end of file From fe101db8dda9e381c3009df3f348169a2d3eb26c Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Wed, 30 Aug 2023 17:16:27 +0100 Subject: [PATCH 2/4] chore: tidy up for v1.x rel --- .github/workflows/audit.yml | 6 +- .github/workflows/manual_release_package.yml | 38 ----------- .github/workflows/release_image.yml | 23 ++++++- .github/workflows/test.yml | 2 +- .github/workflows/update_gems.yml | 66 -------------------- RELEASING.md | 31 ++++++++- script/release-workflow/docker-push.sh | 30 ++++----- 7 files changed, 69 insertions(+), 127 deletions(-) delete mode 100644 .github/workflows/manual_release_package.yml delete mode 100644 .github/workflows/update_gems.yml diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index f4fd86a..6aaa5e9 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -12,7 +12,11 @@ jobs: strategy: fail-fast: false matrix: - DOCKER_TARGET_PLATFORM: [linux/arm, linux/arm64, linux/amd64] + DOCKER_TARGET_PLATFORM: [ + # linux/arm, # Disabled whilst waiting for next release of trivy with published arm artefacts + linux/arm64, + linux/amd64 + ] runs-on: ubuntu-latest env: DOCKER_TARGET_PLATFORM: ${{ matrix.DOCKER_TARGET_PLATFORM }} diff --git a/.github/workflows/manual_release_package.yml b/.github/workflows/manual_release_package.yml deleted file mode 100644 index 9fa0f92..0000000 --- a/.github/workflows/manual_release_package.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Release Docker image with updated packaging - -on: - workflow_dispatch: - inputs: - release: - description: Release number - required: true - type: number - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - uses: ruby/setup-ruby@v1 - - - name: Prepare release - id: prepare-release - run: script/workflows/prepare-release.sh - env: - RELEASE: ${{ inputs.release }} - - - name: Commit and push version and changelog - uses: EndBug/add-and-commit@v4 - with: - add: CHANGELOG.md - author_name: Beth Skurrie via Github Action - author_email: beth@bethesque.com - message: 'chore(release): version ${{ steps.prepare-release.outputs.tag }}' - tag: '${{ steps.prepare-release.outputs.tag }}' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release_image.yml b/.github/workflows/release_image.yml index 155b2a5..9bcaa42 100644 --- a/.github/workflows/release_image.yml +++ b/.github/workflows/release_image.yml @@ -15,7 +15,20 @@ on: - major - minor - patch - + # Sets the first part of the Docker tag - this will update the VERSION file + version: + description: "Custom version, requires increment to be set" + required: false + tag: + description: "Custom Docker image tag (note - this won't update the VERSION file and is for non-prod releases only)" + required: false + push_to_latest: + description: 'Should push to latest' + type: boolean + default: true + docker_repository: + description: The Docker repository to which the image should be published + default: pactfoundation jobs: release: runs-on: ubuntu-latest @@ -35,5 +48,9 @@ jobs: env: DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} - CUSTOM_TAG: ${{ github.event.client_payload.tag }} - INCREMENT: ${{ github.event.inputs.increment }} + DOCKER_IMAGE_ORG_AND_NAME: ${{ github.event.inputs.docker_repository }}/pact-cli + VERSION: ${{ github.event.inputs.version }} + INCREMENT: ${{ github.event.client_payload.increment }}${{ github.event.inputs.increment }} + CUSTOM_TAG: ${{ github.event.client_payload.tag }}${{ github.event.inputs.tag }} + # populate INCREMENT from workflow_dispatch or repository_dispatch + PUSH_TO_LATEST: ${{ github.event.inputs.push_to_latest }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0676ad3..ca88836 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,6 @@ name: Test -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: test: diff --git a/.github/workflows/update_gems.yml b/.github/workflows/update_gems.yml deleted file mode 100644 index a5d7b65..0000000 --- a/.github/workflows/update_gems.yml +++ /dev/null @@ -1,66 +0,0 @@ -# TODO abort if there are no changes to the Gemfile. - -name: Update gems - -on: - repository_dispatch: - types: - - gem-released - workflow_dispatch: - inputs: - released_gem_name: - description: The name of the gem that was released - default: pact - required: false - released_gem_version: - description: The version of the game that was released - required: false - released_gem_version_increment: - description: "The version increment" - required: false - default: "" - type: choice - options: - - "" - - patch - - minor - - major - - pre - -env: - RELEASED_GEM_NAME: '${{ github.event.client_payload.name }}${{ github.event.inputs.released_gem_name }}' - RELEASED_GEM_VERSION: '${{ github.event.client_payload.version }}${{ github.event.inputs.released_gem_version }}' - RELEASED_GEM_INCREMENT: '${{ github.event.client_payload.increment }}${{ github.event.inputs.released_gem_version_increment }}' - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: ruby/setup-ruby@v1 - - - name: Configure git - run: | - git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com" - git config --global user.name "${GITHUB_ACTOR}" - git config --global push.default current - - - name: Update gems - run: script/update-gems-workflow/update-gems.sh - - - name: Detect changes - run: script/update-gems-workflow/detect-changes.sh - - - name: Git commit and push - run: script/update-gems-workflow/git-commit-and-push-gemfile.sh - - - name: Trigger release - uses: peter-evans/repository-dispatch@v1 - if: ${{ github.repository_owner == 'pact-foundation' }} - with: - token: ${{ secrets.GHTOKENFORPACTCLIRELEASE }} - event-type: release-triggered - client-payload: '{"increment": "${{ github.event.client_payload.increment }}${{ github.event.inputs.released_gem_version_increment }}"}' diff --git a/RELEASING.md b/RELEASING.md index c726297..7eacb8b 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,5 +1,34 @@ # Releasing -Manual releases are not generally necessary. When one of the Pact gems is released, it sends a repository dispatch notification with event type `gem-released`, which triggers the `Update gems` Github Action that updates the gems and commits the changes. The `Release` workflow is then triggered by another repository dispatch action of type `release-triggered` which generates the release notes, builds and publishes the Docker image, and creates the git commits and tags. +> Manual releases are not generally necessary. + +When one of the Pact gems is released, it sends a repository dispatch notification with event type `gem-released`, which triggers the `Update gems` Github Action that updates the gems and commits the changes. The `Release` workflow is then triggered by another repository dispatch action of type `release-triggered` which generates the release notes, builds and publishes the Docker image, and creates the git commits and tags. If the packaging code needs to be updated, a manual release can be performed by running the `Release Docker image with updated packaging` workflow from the UI. + +## Automatic releases of the Docker image triggered by the release of one of the Pact gem + +When one of the Pact gems is released by the Github Action in its repository, the `repository_dispatch` action of the `pact-ruby-cli` repository will be invoked with the type `gem-released`, and the release details (name, version, increment). + +This causes the `update_gems.yml` workflow to be run. At the end of the workflow, it will trigger a release by invoking the `repository_dispatch` action with type `release-triggered`, passing in the increment. + +Note: sometimes bundler cannot find the newly released gem straight away, and the job needs to be re-run via the UI. + +### Manual releases of the Docker image triggered by the release of one of the Pact gem + +* On the Github Actions page, select `Update gems` +* Select `Run workflow` +* To attempt to update a particular gem - update the default `released_gem_name` & set the required `released_gem_version` and then click `Run workflow`. This should be the normal process if a Pact gem has been updated. +* To release a non-minor version change, select the `released_gem_version_increment` you want along with the above values, and click `Run workflow`. +* If the `Gemfile.lock` is updated, the results will be committed back to the repository, along with an updated `lib/pact/cli/version.rb` set to the `released_gem_version_increment` (which defaults to minor) +* This will trigger an automated release of the Docker image, where the Docker semver tag will be updated by a the same `released_gem_version_increment` + + +## Manually releasing the Docker image + +* On the Github Actions page, select `Release Docker image` +* Select `Run workflow` +* To release a minor version change, do not set any inputs - just click `Run workflow`. This should be the normal process if you've done some changes to the Docker image. +* To release a non-minor version change, select the increment you want, and click `Run workflow`. +* To set a custom version number (not sure of the usecase for this, but just in case...), set both the version AND the increment and click `Run workflow`. +* To do a completely custom tag, just set the "Custom Docker image tag" and click `Run workflow`. If you do this, the VERSION file will NOT be updated. It is for testing purposes only. \ No newline at end of file diff --git a/script/release-workflow/docker-push.sh b/script/release-workflow/docker-push.sh index a1bd2dd..adbc365 100755 --- a/script/release-workflow/docker-push.sh +++ b/script/release-workflow/docker-push.sh @@ -2,22 +2,18 @@ set -euo >/dev/null -# Enable when we bump the major version to 1 (which we should) -# if [ -n "${MAJOR_TAG}" ]; then -# docker tag ${DOCKER_IMAGE_ORG_AND_NAME}:latest ${DOCKER_IMAGE_ORG_AND_NAME}:${MAJOR_TAG} -# docker push ${DOCKER_IMAGE_ORG_AND_NAME}:${MAJOR_TAG} -# docker push ${DOCKER_IMAGE_ORG_AND_NAME}:latest -# fi +push() { + docker buildx build --platform=linux/amd64,linux/arm64,linux/arm \ + --output=type=image,push=true \ + -t ${DOCKER_IMAGE_ORG_AND_NAME}:$1 . +} +if [ -n "${MAJOR_TAG:-}" ]; then + push ${MAJOR_TAG} +fi -docker buildx build --platform=linux/amd64 \ - --output=type=image,push=true \ - -t ${DOCKER_IMAGE_ORG_AND_NAME}:latest \ - -t ${DOCKER_IMAGE_ORG_AND_NAME}:${TAG} . - ## We will temporarily publish a multi manifest built as $TAG-multi - ## To avoid any issues with existing users. We can ask users for - ## Feedback and then promote to a multi-manifest build -docker buildx build --platform=linux/amd64,linux/arm64,linux/arm \ - --output=type=image,push=true \ - -t ${DOCKER_IMAGE_ORG_AND_NAME}:latest-multi \ - -t ${DOCKER_IMAGE_ORG_AND_NAME}:${TAG}-multi . \ No newline at end of file +push ${TAG} + +if [ "${PUSH_TO_LATEST}" != "false" ]; then + push latest +fi \ No newline at end of file From cc6b37783f13d4b76681aa3e32902dbe2029d836 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Fri, 8 Sep 2023 16:53:05 +0100 Subject: [PATCH 3/4] ci: use github actor for update commits - matches pact-broker-docker repo - broken badges in README removed - unused CI script removed --- .../workflows/update-and-prepare-release.yml | 52 ------------------- .github/workflows/update-gems.yml | 19 +++---- README.md | 4 -- .../workflows/git-commit-and-push-gemfile.sh | 8 +++ 4 files changed, 18 insertions(+), 65 deletions(-) delete mode 100644 .github/workflows/update-and-prepare-release.yml create mode 100644 script/workflows/git-commit-and-push-gemfile.sh diff --git a/.github/workflows/update-and-prepare-release.yml b/.github/workflows/update-and-prepare-release.yml deleted file mode 100644 index c4f568f..0000000 --- a/.github/workflows/update-and-prepare-release.yml +++ /dev/null @@ -1,52 +0,0 @@ -# TODO abort if there are no changes to the Gemfile. - -name: Update gems and prepare to release Docker image - -on: - repository_dispatch: - types: - - gem-released-disabled - workflow_dispatch: - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: ruby/setup-ruby@v1 - - - id: update - run: script/workflows/update.sh - env: - RELEASED_GEM_NAME: ${{ github.event.client_payload.name }} - RELEASED_GEM_VERSION: ${{ github.event.client_payload.version }} - - - name: Commit and push gem file changes - uses: EndBug/add-and-commit@v4 - with: - add: Gemfile.lock - author_name: Beth Skurrie via Github Action - author_email: beth@bethesque.com - message: 'feat(gems): ${{ steps.update.outputs.commit_message }}' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - id: prepare-release - name: Update version and generate changelog - run: script/workflows/prepare-release.sh - env: - INCREMENT: ${{ github.event.client_payload.increment }} - - - name: Commit and push version and changelog - uses: EndBug/add-and-commit@v4 - with: - add: lib/pact/cli/version.rb Gemfile.lock CHANGELOG.md - author_name: Beth Skurrie via Github Action - author_email: beth@bethesque.com - message: 'chore(release): version ${{ steps.prepare-release.outputs.tag }}' - tag: '${{ steps.prepare-release.outputs.tag }}' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-gems.yml b/.github/workflows/update-gems.yml index b721523..106fc32 100644 --- a/.github/workflows/update-gems.yml +++ b/.github/workflows/update-gems.yml @@ -18,22 +18,23 @@ jobs: fetch-depth: 0 - uses: ruby/setup-ruby@v1 + - name: Configure git + run: | + git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com" + git config --global user.name "${GITHUB_ACTOR}" + git config --global push.default current + - id: update run: script/workflows/update.sh env: RELEASED_GEM_NAME: ${{ github.event.client_payload.name }} RELEASED_GEM_VERSION: ${{ github.event.client_payload.version }} - + - name: Commit and push gem file changes - uses: EndBug/add-and-commit@v4 - with: - add: Gemfile.lock - author_name: Beth Skurrie via Github Action - author_email: beth@bethesque.com - message: 'feat(gems): ${{ steps.update.outputs.commit_message }}' + run: script/workflows/git-commit-and-push-gemfile.sh env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + COMMIT_MESSAGE: ${{ steps.update.outputs.commit_message }} + - name: Trigger release uses: peter-evans/repository-dispatch@v1 with: diff --git a/README.md b/README.md index 17462ab..75f967f 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,6 @@ This tool provides an amalgamated CLI of all the Pact CLI tools available in the [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/pact-foundation/pact-msw-adapter/graphs/commit-activity) -[![Linux](https://svgshare.com/i/Zhy.svg)](https://svgshare.com/i/Zhy.svg) -[![macOS](https://svgshare.com/i/ZjP.svg)](https://svgshare.com/i/ZjP.svg) -[![Windows](https://svgshare.com/i/ZhY.svg)](https://svgshare.com/i/ZhY.svg) - [![Build and test](https://github.com/pact-foundation/pact-ruby-cli/actions/workflows/test.yml/badge.svg)](https://github.com/pact-foundation/pact-ruby-cli/actions/workflows/test.yml) [![Audit](https://github.com/pact-foundation/pact-ruby-cli/actions/workflows/audit.yml/badge.svg)](https://github.com/pact-foundation/pact-ruby-cli/actions/workflows/audit.yml) [![Release](https://github.com/pact-foundation/pact-ruby-cli/actions/workflows/release_image.yml/badge.svg)](https://github.com/pact-foundation/pact-ruby-cli/actions/workflows/release_image.yml) diff --git a/script/workflows/git-commit-and-push-gemfile.sh b/script/workflows/git-commit-and-push-gemfile.sh new file mode 100644 index 0000000..5165214 --- /dev/null +++ b/script/workflows/git-commit-and-push-gemfile.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -eou >/dev/null + +git add Gemfile.lock +git commit -m "feat(gems): $COMMIT_MESSAGE + +[ci-skip]" \ No newline at end of file From 430ccf4869441798ff664d0e86f61c9656e4ea71 Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Fri, 8 Sep 2023 16:55:00 +0100 Subject: [PATCH 4/4] chore: rm stale comment --- .github/workflows/update-gems.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/update-gems.yml b/.github/workflows/update-gems.yml index 106fc32..d32c0e3 100644 --- a/.github/workflows/update-gems.yml +++ b/.github/workflows/update-gems.yml @@ -1,5 +1,3 @@ -# TODO abort if there are no changes to the Gemfile. - name: Update gems on: