name: release on: workflow_dispatch: inputs: set-release-version: description: 'Desired delivery version (x.y.z)' required: true type: string concurrency: release jobs: set-context: env: GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} outputs: release_version: ${{ steps.set-release-version.outputs.release_version }} release_branch: ${{ steps.set-release-branch.outputs.release_branch }} name: set-context runs-on: ubuntu-latest steps: - name: Check trigger branch run: | if [ $(echo "${{ github.ref_name }}" | grep -Ec "^master$|^release/") -eq 1 ] ; then echo " - ✅ The branch triggering this workflow is ${{ github.ref_name }}." else echo " - ❌ The branch triggering this workflow is ${{ github.ref_name }} instead of master or release/[0-9].[0-9].[0-9]." exit 1 fi - name: Set release version id: set-release-version run: | echo "release_version=${{ github.event.inputs.set-release-version }}" | tee -a $GITHUB_OUTPUT - name: Set release branch id: set-release-branch run: | if [ $(echo "${{ github.ref_name }}" | grep -c "^release/") -eq 1 ] ; then echo "release_branch=${{ github.ref_name }}" | tee -a $GITHUB_OUTPUT else echo "release_branch=release/${{ github.event.inputs.set-release-version }}" | tee -a $GITHUB_OUTPUT fi clean-release: needs: set-context env: GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} name: clean-release runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 - name: Check release pull request existence id: check-release-pull-request-existence run: | actual_pr_number=$(gh pr list --repo "${{ github.repository }}" --head "${{ needs.set-context.outputs.release_branch }}" --state "open" --json number --jq .[].number) actual_pr_number=${actual_pr_number:-0} echo "actual_pr_number=${actual_pr_number}" | tee -a "${GITHUB_OUTPUT}" if [ ${actual_pr_number} -eq 0 ] ; then echo " - ✅ There is no pull request." echo "release_pr_exists=false" | tee -a $GITHUB_OUTPUT else echo " - ✅ Actual pull request number is ${actual_pr_number}." echo "release_pr_exists=true" | tee -a $GITHUB_OUTPUT fi - name: Close actual pull request if: steps.check-release-pull-request-existence.outputs.release_pr_exists == 'true' run: | comment=" - ✅ Pull request n°${{ steps.check-release-pull-request-existence.outputs.actual_pr_number }} closed before opening new one." gh pr close "${{ steps.check-release-pull-request-existence.outputs.actual_pr_number }}" --comment "${comment}" --delete-branch && gh_exit_code=0 || gh_exit_code=$? if [ ${gh_exit_code} -eq 0 ] ; then echo " - ${comment}" else comment=" - ❌ A problem occurs when attempting to close PR n°${{ steps.check-release-pull-request-existence.outputs.actual_pr_number }}." gh pr comment "${{ steps.check-release-pull-request-existence.outputs.actual_pr_number }}" --body "${comment} Please refer to ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID} logs." echo " - ${comment}" exit 1 fi - name: Check GitHub release existence id: check-github-release-existence run: | gh release list || true escaped_version=$(echo "${{ needs.set-context.outputs.release_version }}" | sed "s#\.#\\\.#g") github_release_exists=$(gh release list | (grep -c "${escaped_version}" || true)) if [ ${github_release_exists} -eq 0 ] ; then echo " - ✅ Github release ${{ needs.set-context.outputs.release_version }} does not exist." echo "github_release_exists=false" | tee -a $GITHUB_OUTPUT else echo " - ✅ Github release ${{ needs.set-context.outputs.release_version }} already exists on remote." echo "github_release_exists=true" | tee -a $GITHUB_OUTPUT fi - name: Delete GitHub release if: steps.check-github-release-existence.outputs.github_release_exists == 'true' run: | gh release delete ${{ needs.set-context.outputs.release_version }} --yes && gh_exit_code=0 || gh_exit_code=$? if [ ${gh_exit_code} -eq 0 ] ; then echo " - ✅ ${{ needs.set-context.outputs.release_version }} GitHub release deleted." else echo " - ❌ A problem occurs when attempting to delete ${{ needs.set-context.outputs.release_version }} GitHub release." exit 1 fi - name: Check tag existence id: check-tag-existence run: | escaped_version=$(echo "${{ needs.set-context.outputs.release_version }}" | sed "s#\.#\\\.#g") tag_exists=$(git ls-remote --tags | (grep -c "${escaped_version}" || true)) if [ ${tag_exists} -eq 0 ] ; then echo " - ✅ The origin/${{ needs.set-context.outputs.release_version }} tag does not exists on remote." echo "release_tag_exists=false" | tee -a $GITHUB_OUTPUT else echo " - ✅ The origin/${{ needs.set-context.outputs.release_version }} tag already exists on remote." echo "release_tag_exists=true" | tee -a $GITHUB_OUTPUT fi - name: Delete release tag if: steps.check-tag-existence.outputs.release_tag_exists == 'true' run: | git push origin --delete ${{ needs.set-context.outputs.release_version }} && git_exit_code=0 || git_exit_code=$? if [ ${git_exit_code} -eq 0 ] ; then echo " - ✅ ${{ needs.set-context.outputs.release_version }} tag deleted." else echo " - ❌ A problem occurs when attempting to delete ${{ needs.set-context.outputs.release_version }} tag." exit 1 fi - name: Check release branch existence id: check-release-branch-existence if: github.ref_name == 'master' run: | escaped_version=$(echo "${{ needs.set-context.outputs.release_version }}" | sed "s#\.#\\\.#g") branch_exists=$(git ls-remote | (grep -c "${escaped_version}" || true)) if [ ${branch_exists} -eq 0 ] ; then echo " - ✅ The origin/${{ needs.set-context.outputs.release_branch }} branch does not exists on remote." echo "release_branch_exists=false" | tee -a $GITHUB_OUTPUT else echo " - ✅ The origin/${{ needs.set-context.outputs.release_branch }} branch already exists on remote." echo "release_branch_exists=true" | tee -a $GITHUB_OUTPUT fi - name: Delete release branch if: github.ref_name == 'master' && steps.check-release-branch-existence.outputs.release_branch_exists == 'true' run: | git push origin --delete ${{ needs.set-context.outputs.release_branch }} && git_exit_code=0 || git_exit_code=$? if [ ${git_exit_code} -eq 0 ] ; then echo " - ✅ ${{ needs.set-context.outputs.release_branch }} branch deleted." else echo " - ❌ A problem occurs when attempting to delete ${{ needs.set-context.outputs.release_branch }} branch." exit 1 fi update-release-branch: needs: - set-context - clean-release env: GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} name: update-release-branch runs-on: ubuntu-latest steps: - name: Checkout repository if: github.ref_name == 'master' uses: actions/checkout@v3 - name: Create release branch if: github.ref_name == 'master' id: create-release-branch run: | git checkout -b "${{ needs.set-context.outputs.release_branch }}" git push origin "${{ needs.set-context.outputs.release_branch }}" && git_exit_code=0 || git_exit_code=$? if [ ${git_exit_code} -eq 0 ] ; then echo " - ✅ ${{ needs.set-context.outputs.release_branch }} branch created." else echo " - ❌ A problem occurs when attempting to create ${{ needs.set-context.outputs.release_branch }} branch." exit 1 fi - name: Checkout new release branch uses: actions/checkout@v3 with: ref: ${{ needs.set-context.outputs.release_branch }} - name: Check CHANGELOG run: | pip install beautifulsoup4 bin/check/changelog.sh - name: Update version run: | hurl_packages="hurl_core hurl hurlfmt" for package in ${hurl_packages} ; do cargo_toml="packages/${package}/Cargo.toml" sed -i "s/^version.*/version = \"${{ needs.set-context.outputs.release_version }}\"/" "${cargo_toml}" echo "----------------------------" echo " > package version for ${cargo_toml}" echo " $(grep "^version =" "${cargo_toml}")" for dep_package in ${hurl_packages} ; do if [ $(grep -c "^${dep_package} =" "${cargo_toml}") -gt 0 ] ; then sed -i "s/^${dep_package} = { version .*/${dep_package} = { version = \"${{ needs.set-context.outputs.release_version }}\", path = \"..\/${dep_package}\" }/" "${cargo_toml}" echo " > ${dep_package} dep package version for ${cargo_toml}" echo " $(grep "^${dep_package} =" "${cargo_toml}")" fi done done - name: Cargo update run: | ./bin/update_crates.sh - name: Update installation doc run: | # TODO: create a dedicated check script version_doc="docs/installation.md" old_version=$(grep "apt install" "${version_doc}" | grep "hurl" | cut --delimiter '/' --field 2- | cut --delimiter '_' --field 2) echo "old_version=${old_version}" sed -i "s/${old_version}/${{ needs.set-context.outputs.release_version }}/g" "${version_doc}" grep "${{ needs.set-context.outputs.release_version }}" "${version_doc}" - name: Update man run: | for package in hurl hurlfmt ; do python3 bin/release/gen_manpage.py "docs/manual/${package}.md" > "docs/manual/${package}.1" done - name: Update general docs run: | python3 bin/docs/build_man_md.py docs/manual/hurl.md > docs/manual.md python3 bin/docs/build_readme.py github > README.md python3 bin/docs/build_readme.py crates > packages/hurl/README.md - name: Init git bot context uses: crazy-max/ghaction-import-gpg@v5 with: gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} git_committer_name: "hurl-bot" git_committer_email: "bot@hurl.dev" git_user_signingkey: true git_commit_gpgsign: true - name: Push create release commits run: | git diff --exit-code && diff=false || diff=true if [ "${diff}" == "true" ] ; then git commit -am "Create ${{ needs.set-context.outputs.release_version }} release" git push && git_exit_code=0 || git_exit_code=$? if [ ${git_exit_code} -eq 0 ] ; then echo " - ✅ commits pushed to ${{ needs.set-context.outputs.release_branch }}." else echo " - ❌ A problem occurs when attempting to push create release commits to ${{ needs.set-context.outputs.release_branch }} branch." exit 1 fi else echo " - ✅ no changes" fi - name: Archive artifacts uses: actions/upload-artifact@v3 if: ${{ always() }} with: name: release-changelog path: | release_changelog.md package-release: needs: - set-context - clean-release - update-release-branch name: package-release uses: ./.github/workflows/package.yml with: branch: ${{ needs.set-context.outputs.release_branch }} deliver-github-release: env: GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} REPO: ${{ github.repository }} needs: - set-context - clean-release - update-release-branch - package-release name: deliver-github-release runs-on: ubuntu-latest steps: - name: Checkout new release branch uses: actions/checkout@v3 with: ref: ${{ needs.set-context.outputs.release_branch }} - name: Init git bot context uses: crazy-max/ghaction-import-gpg@v5 with: gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} git_committer_name: "hurl-bot" git_committer_email: "bot@hurl.dev" git_user_signingkey: true git_commit_gpgsign: true - uses: actions/download-artifact@master with: path: artifacts - name: Push tag run: | git tag -a ${{ needs.set-context.outputs.release_version }} -m "Release ${{ needs.set-context.outputs.release_version }}" git tag -n git push --tags && git_exit_code=0 || git_exit_code=$? if [ ${git_exit_code} -eq 0 ] ; then echo " - ✅ ${{ needs.set-context.outputs.release_version }} tag created." git fetch else echo " - ❌ A problem occurs when attempting to create ${{ needs.set-context.outputs.release_version }} tag." exit 1 fi - name: Deliver release run: | cat CHANGELOG.md | python3 bin/release/changelog_extract.py ${{ needs.set-context.outputs.release_version }} > release_changelog.md gh release create ${{ needs.set-context.outputs.release_version }} \ --target ${{ needs.set-context.outputs.release_branch }} \ --notes-file release_changelog.md \ --title ${{ needs.set-context.outputs.release_version }} \ --draft \ artifacts/release-deb-x64-artifacts/hurl_"${{ needs.set-context.outputs.release_version }}"_amd64.deb \ artifacts/release-generic-linux-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-x86_64-linux.tar.gz \ artifacts/release-macos-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-x86_64-macos.tar.gz \ artifacts/release-windows-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-win64-installer.exe \ artifacts/release-windows-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-win64.zip && gh_exit_code=0 || gh_exit_code=$? if [ ${gh_exit_code} -eq 0 ] ; then echo " - ✅ Github release ${{ needs.set-context.outputs.release_version }} created." else echo " - ❌ A problem occurs when attempting to create GitHub release ${{ needs.set-context.outputs.release_version }}." exit 1 fi - name: Create new pull request run: | GITHUB_TOKEN=${{ secrets.HURL_BOT_TOKEN }} { echo "⚠ This is a GitHub releasing PR." echo "- Please use \`/accept --release\` if you want to automatically update master branch to next SNAPSHOT version" } > file-body.txt gh pr create \ --title "Merge GitHub ${{ needs.set-context.outputs.release_branch }} into ${{ github.ref_name }}" \ --body-file file-body.txt \ --base master \ --label bot && gh_exit_code=0 || gh_exit_code=$? if [ ${gh_exit_code} -eq 0 ] ; then new_pr_number=$(gh pr list --repo "${{ github.repository }}" --head "${{ needs.set-context.outputs.release_branch }}" --state "open" --json number --jq .[].number) echo " - ✅ Creation of pull request n°${new_pr_number} succeeds." else echo " - ❌ A problem occurs when attempting to create new pull request." exit 1 fi