From 4b20d74bb20dfecb6e624d76e397017afe499af0 Mon Sep 17 00:00:00 2001 From: Darren Murray Date: Tue, 27 Apr 2021 12:17:08 +0100 Subject: [PATCH] ci: switch PR test from CircleCI to CodeFresh Signed-off-by: Darren Murray --- .circleci/config.yml | 120 -------------- README.md | 2 +- scripts/release.sh | 261 ++----------------------------- scripts/release_helpers.sh | 309 +++++++++++++++++++++++++++++++++++++ 4 files changed, 321 insertions(+), 371 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 scripts/release_helpers.sh diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index b1dca40..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,120 +0,0 @@ -version: 2.1 - -parameters: - slack-mentions: - type: string - default: "S01JP5A3ACQ" - only_for_branches: - type: string - default: "main" - -orbs: - slack: circleci/slack@3.4.2 - jq: circleci/jq@2.1.0 - -executors: - terraform12: - docker: - - image: techallylw/terraform:12 - terraform13: - docker: - - image: techallylw/terraform:13 - alpine: - docker: - - image: cibuilds/base:latest - resource_class: small - -jobs: - terraform12-test: - executor: terraform12 - steps: - - checkout - - run: scripts/ci_tests.sh - - slack/status: - fail_only: true - mentions: << pipeline.parameters.slack-mentions >> - only_for_branches: <> - terraform13-test: - executor: terraform13 - steps: - - checkout - - run: scripts/ci_tests.sh - - slack/status: - fail_only: true - mentions: << pipeline.parameters.slack-mentions >> - only_for_branches: <> - verify-release: - executor: alpine - steps: - - checkout - - run: scripts/release.sh verify - trigger-release: - executor: alpine - steps: - - checkout - - add_ssh_keys: - fingerprints: - - "c4:03:1e:48:4c:d4:dd:8b:5a:e3:59:8c:18:4e:00:d5" - - run: scripts/release.sh trigger - release: - executor: alpine - steps: - - checkout - - jq/install - - slack/notify: - mentions: << pipeline.parameters.slack-mentions >> - message: Releasing new version of this repository - - run: scripts/release.sh publish - - slack/status: - mentions: << pipeline.parameters.slack-mentions >> - -workflows: - version: 2 - test-trigger-release: - jobs: - - terraform12-test: - context: - - techally_api_key - - terraform13-test: - context: - - techally_api_key - - trigger-release: - requires: - - terraform12-test - - terraform13-test - filters: - branches: - only: main - - verify-release: - jobs: - - verify-release: - filters: - branches: - only: release - - release-from-tag: - jobs: - - release: - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - context: - - techally_releases - - nightly: - triggers: - - schedule: - cron: "0 12 * * *" - filters: - branches: - only: main - jobs: - - terraform12-test: - context: - - techally_api_key - - terraform13-test: - context: - - techally_api_key diff --git a/README.md b/README.md index 46d7fad..09d1b99 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # terraform-aws-ecr [![GitHub release](https://img.shields.io/github/release/lacework/terraform-aws-ecr.svg)](https://github.com/lacework/terraform-aws-ecr/releases/) -[![CircleCI status](https://circleci.com/gh/lacework/terraform-aws-ecr.svg?style=shield)](https://circleci.com/gh/lacework/terraform-aws-ecr) +![Codefresh build status]( https://g.codefresh.io/api/badges/pipeline/lacework/terraform-modules%2Ftest-compatibility?type=cf-1&key=eyJhbGciOiJIUzI1NiJ9.NWVmNTAxOGU4Y2FjOGQzYTkxYjg3ZDEx.RJ3DEzWmBXrJX7m38iExJ_ntGv4_Ip8VTa-an8gBwBo)]( https://g.codefresh.io/pipelines/edit/new/builds?id=607e25e6728f5a6fba30431b&pipeline=test-compatibility&projects=terraform-modules&projectId=607db54b728f5a5f8930405d) A Terraform Module to integrate Amazon Container Registries (ECR) with Lacework. diff --git a/scripts/release.sh b/scripts/release.sh index b7e4e2a..e5ea349 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -7,11 +7,22 @@ # Author:: Salim Afiune Maya () # set -eou pipefail +# common release functions +source scripts/release_helpers.sh +# Required Variables readonly org_name=lacework readonly project_name=terraform-aws-ecr readonly git_user="Lacework Inc." readonly git_email="ops+releng@lacework.net" +readonly required_files_for_release=( + RELEASE_NOTES.md + CHANGELOG.md + VERSION +) +readonly main_branch=main + +# Variable that changes during release VERSION=$(cat VERSION) usage() { @@ -54,254 +65,4 @@ main() { esac } -trigger_release() { - if [[ "$VERSION" =~ "-dev" ]]; then - log "No release needed. (VERSION=${VERSION})" - log "" - log "Read more about the release process at:" - log " - https://github.com/${org_name}/${project_name}/wiki/Release-Process" - else - log "VERSION ready to be released to 'x.y.z' tag. Triggering a release!" - log "" - tag_release - bump_version - fi -} - -verify_release() { - log "verifying new release" - _changed_file=$(git whatchanged --name-only --pretty="" origin..HEAD) - _required_files_for_release=( - RELEASE_NOTES.md - CHANGELOG.md - VERSION - ) - for f in "${_required_files_for_release[@]}"; do - if [[ "$_changed_file" =~ "$f" ]]; then - log "(required) '$f' has been modified. Great!" - else - warn "$f needs to be updated" - warn "" - warn "Read more about the release process at:" - warn " - https://github.com/${org_name}/${project_name}/wiki/Release-Process" - exit 123 - fi - done - - if [[ "$VERSION" =~ "-dev" ]]; then - warn "the 'VERSION' needs to be cleaned up to be only 'x.y.z' tag" - warn "" - warn "Read more about the release process at:" - warn " - https://github.com/${org_name}/${project_name}/wiki/Release-Process" - exit 123 - else - log "(required) VERSION has been cleaned up to 'x.y.z' tag. Great!" - fi -} - -prepare_release() { - log "preparing new release" - prerequisites - remove_tag_version - generate_release_notes - update_changelog - push_release -} - -publish_release() { - log "releasing v$VERSION" - create_release -} - -update_changelog() { - log "updating CHANGELOG.md" - _changelog=$(cat CHANGELOG.md) - echo "# v$VERSION" > CHANGELOG.md - echo "" >> CHANGELOG.md - echo "$(cat CHANGES.md)" >> CHANGELOG.md - echo "---" >> CHANGELOG.md - echo "$_changelog" >> CHANGELOG.md - # clean changes file since we don't need it anymore - rm CHANGES.md -} - -load_list_of_changes() { - latest_version=$(find_latest_version) - local _list_of_changes=$(git log --no-merges --pretty="* %s (%an)([%h](https://github.com/${org_name}/${project_name}/commit/%H))" ${latest_version}..main) - - # init changes file - true > CHANGES.md - - _feat=$(echo "$_list_of_changes" | grep "\* feat[:(]") - _refactor=$(echo "$_list_of_changes" | grep "\* refactor[:(]") - _perf=$(echo "$_list_of_changes" | grep "\* perf[:(]") - _fix=$(echo "$_list_of_changes" | grep "\* fix[:(]") - _doc=$(echo "$_list_of_changes" | grep "\* doc[:(]") - _docs=$(echo "$_list_of_changes" | grep "\* docs[:(]") - _style=$(echo "$_list_of_changes" | grep "\* style[:(]") - _chore=$(echo "$_list_of_changes" | grep "\* chore[:(]") - _build=$(echo "$_list_of_changes" | grep "\* build[:(]") - _ci=$(echo "$_list_of_changes" | grep "\* ci[:(]") - _test=$(echo "$_list_of_changes" | grep "\* test[:(]") - - if [ "$_feat" != "" ]; then - echo "## Features" >> CHANGES.md - echo "$_feat" >> CHANGES.md - fi - - if [ "$_refactor" != "" ]; then - echo "## Refactor" >> CHANGES.md - echo "$_refactor" >> CHANGES.md - fi - - if [ "$_perf" != "" ]; then - echo "## Performance Improvements" >> CHANGES.md - echo "$_perf" >> CHANGES.md - fi - - if [ "$_fix" != "" ]; then - echo "## Bug Fixes" >> CHANGES.md - echo "$_fix" >> CHANGES.md - fi - - if [ "${_docs}${_doc}" != "" ]; then - echo "## Documentation Updates" >> CHANGES.md - if [ "$_doc" != "" ]; then echo "$_doc" >> CHANGES.md; fi - if [ "$_docs" != "" ]; then echo "$_docs" >> CHANGES.md; fi - fi - - if [ "${_style}${_chore}${_build}${_ci}${_test}" != "" ]; then - echo "## Other Changes" >> CHANGES.md - if [ "$_style" != "" ]; then echo "$_style" >> CHANGES.md; fi - if [ "$_chore" != "" ]; then echo "$_chore" >> CHANGES.md; fi - if [ "$_build" != "" ]; then echo "$_build" >> CHANGES.md; fi - if [ "$_ci" != "" ]; then echo "$_ci" >> CHANGES.md; fi - if [ "$_test" != "" ]; then echo "$_test" >> CHANGES.md; fi - fi -} - -generate_release_notes() { - log "generating release notes at RELEASE_NOTES.md" - load_list_of_changes - echo "# Release Notes" > RELEASE_NOTES.md - echo "Another day, another release. These are the release notes for the version \`v$VERSION\`." >> RELEASE_NOTES.md - echo "" >> RELEASE_NOTES.md - echo "$(cat CHANGES.md)" >> RELEASE_NOTES.md -} - -push_release() { - log "commiting and pushing the release to github" - git checkout -B release - git commit -am "Release v$VERSION" - git push origin release - log "" - log "Follow the above url and open a pull request" -} - -tag_release() { - local _tag="v$VERSION" - log "creating github tag: $_tag" - git tag "$_tag" - git push origin "$_tag" -} - -prerequisites() { - local _branch=$(git rev-parse --abbrev-ref HEAD) - if [ "$_branch" != "main" ]; then - warn "Releases must be generated from the 'main' branch. (current $_branch)" - warn "Switch to the main branch and try again." - exit 127 - fi - - local _unsaved_changes=$(git status -s) - if [ "$_unsaved_changes" != "" ]; then - warn "You have unsaved changes in the main branch. Are you resuming a release?" - warn "To resume a release you have to start over, to remove all unsaved changes run the command:" - warn " git reset --hard origin/main" - exit 127 - fi -} - -find_latest_version() { - local _pattern="v[0-9]\+.[0-9]\+.[0-9]\+" - local _versions - _versions=$(git ls-remote --tags --quiet | grep $_pattern | tr '/' ' ' | awk '{print $NF}') - echo "$_versions" | tr '.' ' ' | sort -nr -k 1 -k 2 -k 3 | tr ' ' '.' | head -1 -} - -remove_tag_version() { - echo $VERSION | awk -F. '{printf("%d.%d.%d", $1, $2, $3)}' > VERSION - VERSION=$(cat VERSION) - log "updated version to v$VERSION" -} - -bump_version() { - log "updating version after tagging release" - latest_version=$(find_latest_version) - - if [[ "v$VERSION" == "$latest_version" ]]; then - case "${1:-}" in - major) - echo $VERSION | awk -F. '{printf("%d.%d.%d-dev", $1+1, $2, $3)}' > VERSION - ;; - minor) - echo $VERSION | awk -F. '{printf("%d.%d.%d-dev", $1, $2+1, $3)}' > VERSION - ;; - *) - echo $VERSION | awk -F. '{printf("%d.%d.%d-dev", $1, $2, $3+1)}' > VERSION - ;; - esac - VERSION=$(cat VERSION) - log "version bumped from $latest_version to v$VERSION" - else - log "skipping version bump. Already bumped to v$VERSION" - return - fi - - log "commiting and pushing the version bump to github" - git config --global user.email $git_email - git config --global user.name $git_user - git add VERSION - git commit -m "version bump to v$VERSION" - git push origin main -} - -create_release() { - local _tag - _tag=$(git describe --tags) - local _body="/tmp/release.json" - - log "generating GH release $_tag" - generate_release_body "$_body" - curl -XPOST -H "Authorization: token $GITHUB_TOKEN" --data "@$_body" \ - https://api.github.com/repos/${org_name}/${project_name}/releases - - log "the release has been completed!" - log "" - log " -> https://github.com/${org_name}/${project_name}/releases/tag/${_tag}" -} - -generate_release_body() { - _file=${1:-release.json} - _tag=$(git describe --tags) - _release_notes=$(jq -aRs . <<< cat RELEASE_NOTES.md) - cat < $_file -{ - "tag_name": "$_tag", - "name": "$_tag", - "draft": false, - "prerelease": false, - "body": $_release_notes -} -EOF -} - -log() { - echo "--> ${project_name}: $1" -} - -warn() { - echo "xxx ${project_name}: $1" >&2 -} - main "$@" || exit 99 diff --git a/scripts/release_helpers.sh b/scripts/release_helpers.sh new file mode 100644 index 0000000..3b7b172 --- /dev/null +++ b/scripts/release_helpers.sh @@ -0,0 +1,309 @@ +# +# Name:: release_helpers.sh +# Description:: A set of helper funtions to be used by our release.sh script +# Author:: Salim Afiune Maya () +# + +log() { + echo "--> ${project_name}: $1" +} + +warn() { + echo "xxx ${project_name}: $1" >&2 +} + +trigger_release() { + if [[ "$VERSION" =~ "-dev" ]]; then + log "No release needed. (VERSION=${VERSION})" + log "" + log "Read more about the release process at:" + log " - https://github.com/${org_name}/${project_name}/wiki/Release-Process" + else + log "VERSION ready to be released to 'x.y.z' tag. Triggering a release!" + log "" + tag_release + sleep 5 # just so github has the new tag available + bump_version + fi +} + +tag_release() { + local _tag="v$VERSION" + log "creating github tag: $_tag" + git tag "$_tag" + git push origin "$_tag" +} + +find_latest_version() { + local _pattern="v[0-9]\+.[0-9]\+.[0-9]\+" + local _versions + _versions=$(git ls-remote --tags --quiet | grep $_pattern | tr '/' ' ' | awk '{print $NF}') + if [ "$_versions" != "" ]; then + echo "$_versions" | tr '.' ' ' | sort -nr -k 1 -k 2 -k 3 | tr ' ' '.' | head -1 + else + git rev-list --max-parents=0 HEAD + fi +} + +bump_version() { + log "updating version after tagging release" + latest_version=$(find_latest_version) + + if [[ "v$VERSION" == "$latest_version" ]]; then + case "${1:-}" in + major) + echo $VERSION | awk -F. '{printf("%d.%d.%d-dev", $1+1, $2, $3)}' > VERSION + ;; + minor) + echo $VERSION | awk -F. '{printf("%d.%d.%d-dev", $1, $2+1, $3)}' > VERSION + ;; + *) + echo $VERSION | awk -F. '{printf("%d.%d.%d-dev", $1, $2, $3+1)}' > VERSION + ;; + esac + VERSION=$(cat VERSION) + log "version bumped from $latest_version to v$VERSION" + else + log "skipping version bump. Already bumped to v$VERSION" + return + fi + + log "commiting and pushing the version bump to github" + git config --global user.email $git_email + git config --global user.name $git_user + git_add_version_files + git commit -m "chore: version bump to v$VERSION" + git push origin $main_branch +} + +# @afiune explain why this is here? To override it +git_add_version_files() { + git add VERSION +} + +verify_release() { + log "verifying new release" + _changed_file=$(git whatchanged --name-only --pretty="" origin..HEAD) + for f in "${required_files_for_release[@]}"; do + if [[ "$_changed_file" =~ "$f" ]]; then + log "(required) '$f' has been modified. Great!" + else + warn "$f needs to be updated" + warn "" + warn "Read more about the release process at:" + warn " - https://github.com/${org_name}/${project_name}/wiki/Release-Process" + exit 123 + fi + done + + if [[ "$VERSION" =~ "-dev" ]]; then + warn "the 'VERSION' needs to be cleaned up to be only 'x.y.z' tag" + warn "" + warn "Read more about the release process at:" + warn " - https://github.com/${org_name}/${project_name}/wiki/Release-Process" + exit 123 + else + log "(required) VERSION has been cleaned up to 'x.y.z' tag. Great!" + fi +} + +publish_release() { + log "releasing v$VERSION" + create_release +} + +create_release() { + local _tag + _tag=$(git describe --tags) + local _body="/tmp/release.json" + + log "generating GH release $_tag" + generate_release_body "$_body" + curl -XPOST -H "Authorization: token $GITHUB_TOKEN" --data "@$_body" \ + https://api.github.com/repos/${org_name}/${project_name}/releases + + log "the release has been completed!" + log "" + log " -> https://github.com/${org_name}/${project_name}/releases/tag/${_tag}" +} + +prepare_release() { + log "preparing new release" + prerequisites + remove_tag_version + check_for_minor_version_bump + generate_release_notes + update_changelog + push_release + open_pull_request +} + +push_release() { + log "commiting and pushing the release to github" + _version_no_tag=$(echo $VERSION | awk -F. '{printf("%d.%d.%d", $1, $2, $3)}') + if [ "$CI" != "" ]; then + git config --global user.email $git_email + git config --global user.name $git_user + fi + git checkout -B release + git commit -am "release: v$_version_no_tag" + git push origin release -f +} + +open_pull_request() { + local _body="/tmp/pr.json" + local _pr="/tmp/pr.out" + + log "opening GH pull request" + generate_pr_body "$_body" + curl -XPOST -H "Authorization: token $GITHUB_TOKEN" --data "@$_body" \ + https://api.github.com/repos/${org_name}/${project_name}/pulls > $_pr + + _pr_url=$(jq .html_url $_pr) + log "" + log "It is time to review the release!" + log " $_pr_url" +} + +update_changelog() { + log "updating CHANGELOG.md" + _changelog=$(cat CHANGELOG.md) + echo "# v$VERSION" > CHANGELOG.md + echo "" >> CHANGELOG.md + echo "$(cat CHANGES.md)" >> CHANGELOG.md + echo "---" >> CHANGELOG.md + echo "$_changelog" >> CHANGELOG.md + # clean changes file since we don't need it anymore + rm CHANGES.md +} + +generate_release_notes() { + log "generating release notes at RELEASE_NOTES.md" + load_list_of_changes + echo "# Release Notes" > RELEASE_NOTES.md + echo "Another day, another release. These are the release notes for the version \`v$VERSION\`." >> RELEASE_NOTES.md + echo "" >> RELEASE_NOTES.md + echo "$(cat CHANGES.md)" >> RELEASE_NOTES.md +} + +load_list_of_changes() { + latest_version=$(find_latest_version) + local _list_of_changes=$(git log --no-merges --pretty="* %s (%an)([%h](https://github.com/${org_name}/${project_name}/commit/%H))" ${latest_version}..${main_branch}) + + # init changes file + true > CHANGES.md + + _feat=$(echo "$_list_of_changes" | grep "\* feat[:(]") + _refactor=$(echo "$_list_of_changes" | grep "\* refactor[:(]") + _perf=$(echo "$_list_of_changes" | grep "\* perf[:(]") + _fix=$(echo "$_list_of_changes" | grep "\* fix[:(]") + _doc=$(echo "$_list_of_changes" | grep "\* doc[:(]") + _docs=$(echo "$_list_of_changes" | grep "\* docs[:(]") + _style=$(echo "$_list_of_changes" | grep "\* style[:(]") + _chore=$(echo "$_list_of_changes" | grep "\* chore[:(]") + _build=$(echo "$_list_of_changes" | grep "\* build[:(]") + _ci=$(echo "$_list_of_changes" | grep "\* ci[:(]") + _test=$(echo "$_list_of_changes" | grep "\* test[:(]") + + if [ "$_feat" != "" ]; then + echo "## Features" >> CHANGES.md + echo "$_feat" >> CHANGES.md + fi + + if [ "$_refactor" != "" ]; then + echo "## Refactor" >> CHANGES.md + echo "$_refactor" >> CHANGES.md + fi + + if [ "$_perf" != "" ]; then + echo "## Performance Improvements" >> CHANGES.md + echo "$_perf" >> CHANGES.md + fi + + if [ "$_fix" != "" ]; then + echo "## Bug Fixes" >> CHANGES.md + echo "$_fix" >> CHANGES.md + fi + + if [ "${_docs}${_doc}" != "" ]; then + echo "## Documentation Updates" >> CHANGES.md + if [ "$_doc" != "" ]; then echo "$_doc" >> CHANGES.md; fi + if [ "$_docs" != "" ]; then echo "$_docs" >> CHANGES.md; fi + fi + + if [ "${_style}${_chore}${_build}${_ci}${_test}" != "" ]; then + echo "## Other Changes" >> CHANGES.md + if [ "$_style" != "" ]; then echo "$_style" >> CHANGES.md; fi + if [ "$_chore" != "" ]; then echo "$_chore" >> CHANGES.md; fi + if [ "$_build" != "" ]; then echo "$_build" >> CHANGES.md; fi + if [ "$_ci" != "" ]; then echo "$_ci" >> CHANGES.md; fi + if [ "$_test" != "" ]; then echo "$_test" >> CHANGES.md; fi + fi +} + +prerequisites() { + local _branch=$(git rev-parse --abbrev-ref HEAD) + if [ "$_branch" != "${main_branch}" ]; then + warn "Releases must be generated from the '${main_branch}' branch. (current $_branch)" + warn "Switch to the ${main_branch} branch and try again." + exit 127 + fi + + local _unsaved_changes=$(git status -s) + if [ "$_unsaved_changes" != "" ]; then + warn "You have unsaved changes in the ${main_branch} branch. Are you resuming a release?" + warn "To resume a release you have to start over, to remove all unsaved changes run the command:" + warn " git reset --hard origin/${main_branch}" + exit 127 + fi +} + +check_for_minor_version_bump() { + if release_contains_features; then + log "new feature detected, minor version bump" + echo $VERSION | awk -F. '{printf("%d.%d.0", $1, $2+1)}' > VERSION + VERSION=$(cat VERSION) + log "updated version to v$VERSION" + fi +} + +release_contains_features() { + latest_version=$(find_latest_version) + git log --no-merges --pretty="%s" ${latest_version}..${main_branch} | grep "feat[:(]" >/dev/null + return $? +} + +remove_tag_version() { + echo $VERSION | awk -F. '{printf("%d.%d.%d", $1, $2, $3)}' > VERSION + VERSION=$(cat VERSION) + log "updated version to v$VERSION" +} + +generate_release_body() { + _file=${1:-release.json} + _tag=$(git describe --tags) + _release_notes=$(jq -aRs . <<< cat RELEASE_NOTES.md) + cat < $_file +{ + "tag_name": "$_tag", + "name": "$_tag", + "draft": false, + "prerelease": false, + "body": $_release_notes +} +EOF +} + +generate_pr_body() { + _file=${1:-pr.json} + _version_no_tag=$(echo $VERSION | awk -F. '{printf("%d.%d.%d", $1, $2, $3)}') + _release_notes=$(jq -aRs . <<< cat RELEASE_NOTES.md) + cat < $_file +{ + "base": "${main_branch}", + "head": "release", + "title": "Release v$_version_no_tag", + "body": $_release_notes +} +EOF +}