Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Automatic release based on version bump #830

Merged
merged 3 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 146 additions & 42 deletions .github/workflows/bump-version.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,148 @@
name: Bump Version

on:
pull_request:
branches:
- main
types: [closed]
workflow_run:
workflows: ["Prepare Version Bump"]
types:
- completed

jobs:
bump-version:
runs-on: ubuntu-latest

env:
GH_PUSH_TOKEN: ${{ secrets.GH_PUSH_TOKEN }}

steps:

- name: Checkout
uses: actions/checkout@v4
if: env.GH_PUSH_TOKEN != ''
with:
token: ${{ env.GH_PUSH_TOKEN }}

- name: configure git
if: env.GH_PUSH_TOKEN != ''
run: |
git remote set-url origin https://[email protected]/cuttle-cards/cuttle
git config --global user.name "Cuttle Continuous Integration"
git config --global user.email "[email protected]"


- name: bump patch version
if: contains(github.event.pull_request.labels.*.name, 'version-patch') && env.GH_PUSH_TOKEN != ''
run: npm run version:patch

- name: bump minor version
if: contains(github.event.pull_request.labels.*.name, 'version-minor') && env.GH_PUSH_TOKEN != ''
run: npm run version:minor

- name: bump major version
if: contains(github.event.pull_request.labels.*.name, 'version-major') && env.GH_PUSH_TOKEN != ''
run: npm run version:major

- name: push
if: env.GH_PUSH_TOKEN != ''
run: git push origin main
check-previous-workflow:
runs-on: ubuntu-latest
steps:
- name: Check if previous workflow was successful
run: |
if [[ "${{ github.event.workflow_run.conclusion }}" != "success" ]]; then
echo "### ❌ Previous Workflow Failed" >> $GITHUB_STEP_SUMMARY
echo "The triggering workflow did not complete successfully, please review the workflow run details." >> $GITHUB_STEP_SUMMARY
exit 1
else
echo "### ✅ Previous Workflow Succeeded" >> $GITHUB_STEP_SUMMARY
fi
shell: bash

check-token:
runs-on: ubuntu-latest
steps:
- name: Check GH_PUSH_TOKEN
itsalaidbacklife marked this conversation as resolved.
Show resolved Hide resolved
run: |
if [[ -z "${{ secrets.GH_PUSH_TOKEN }}" ]]; then
echo "### ❌ GH_PUSH_TOKEN Error" >> $GITHUB_STEP_SUMMARY
echo "The \`GH_PUSH_TOKEN\` secret is not set, which is required for git operations." >> $GITHUB_STEP_SUMMARY
exit 1
else
echo "### ✅ GH_PUSH_TOKEN Found" >> $GITHUB_STEP_SUMMARY
fi
shell: bash

download-artifact:
needs: [check-previous-workflow, check-token]
runs-on: ubuntu-latest
steps:
# No need to retry this logic, the previous workflow will fail if
# the artifact isn't uploaded
- name: Download version artifact
uses: actions/github-script@v7
env:
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
with:
script: |
const artifact_name = `version-${process.env.WORKFLOW_RUN_ID}`;
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: process.env.WORKFLOW_RUN_ID,
});
const matchArtifact = artifacts.data.artifacts.find((artifact) =>
artifact.name === artifact_name
);

if (!matchArtifact) {
console.log(`### ❌ Artifact ${artifact_name} is not available`);
process.exit(1);
}

console.log(`Artifact ${artifact_name} with ID ${matchArtifact.id} is available`);
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
const fs = require('fs');
fs.writeFileSync('./version-artifact.zip', Buffer.from(download.data));
const unzip = require('child_process').execSync('unzip -j "version-artifact.zip" "version.txt" -d .');
if (!fs.existsSync('version.txt')) {
console.log('### ❌ Failed to extract version.txt');
process.exit(1);
}

- name: Read BUMP_TYPE from version file and set as output
id: read_bump_type
run: |
BUMP_TYPE=$(cat version.txt)
echo "### 📄 Bump Type" >> $GITHUB_STEP_SUMMARY
echo "The BUMP_TYPE set for this run is \`${BUMP_TYPE}\`." >> $GITHUB_STEP_SUMMARY
echo "BUMP_TYPE=${BUMP_TYPE}" >> $GITHUB_OUTPUT
shell: bash

outputs:
BUMP_TYPE: ${{ steps.read_bump_type.outputs.BUMP_TYPE }}

bump-and-push-version:
needs: download-artifact
runs-on: ubuntu-latest
steps:
- name: Check out code with token
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PUSH_TOKEN }}

- name: Configure Git
run: |
git config --global user.email "[email protected]"
git config --global user.name "GitHub Actions"

- name: Bump Version, create tag and commit
id: bump_version
run: |
BUMP_TYPE=${{ needs.download-artifact.outputs.BUMP_TYPE }}
echo "Current BUMP_TYPE: $BUMP_TYPE"
npm version "$BUMP_TYPE" --no-git-tag-version
VERSION=$(node -p "require('./package.json').version")
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
git commit -am "Bump version to $VERSION"
git tag "$VERSION"
git push origin HEAD:main
git push origin "$VERSION"
shell: bash

- name: Version Bump Summary
run: |
VERSION=${{ steps.bump_version.outputs.VERSION }}
echo "### 🚀 Version Bumped" >> $GITHUB_STEP_SUMMARY
echo "The project version has been increased to **$VERSION**." >> $GITHUB_STEP_SUMMARY
echo "This includes a new Git tag and commit for **$VERSION** which has been pushed to the repository." >> $GITHUB_STEP_SUMMARY
echo "Check out the [commit history](https://github.com/${{ github.repository }}/commits/main) to see the changes." >> $GITHUB_STEP_SUMMARY
shell: bash

outputs:
VERSION: ${{ steps.bump_version.outputs.VERSION }}

create-release:
needs: bump-and-push-version
runs-on: ubuntu-latest
steps:
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.bump-and-push-version.outputs.VERSION }}
name: ${{ needs.bump-and-push-version.outputs.VERSION }}
env:
GITHUB_TOKEN: ${{ secrets.GH_PUSH_TOKEN }}

- name: Release Summary
run: |
echo "### 🎉 New Release Created" >> $GITHUB_STEP_SUMMARY
echo "A new release version \`${{ needs.bump-and-push-version.outputs.VERSION }}\` has been published!" >> $GITHUB_STEP_SUMMARY
echo "[View the new release](https://github.com/${{ github.repository }}/releases/tag/v${{ needs.bump-and-push-version.outputs.VERSION }})" >> $GITHUB_STEP_SUMMARY
70 changes: 70 additions & 0 deletions .github/workflows/prepare-version-bump.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Prepare Version Bump
'on':
pull_request:
types:
- closed
branches:
- main
jobs:
check-merged:
runs-on: ubuntu-latest
outputs:
merged: ${{ steps.check.outputs.merged }}
steps:
- name: Check if PR is merged
id: check
run: |
if [[ "${{ github.event.pull_request.merged }}" != "true" ]]; then
echo "### ❌ Pull Request Not Merged" >> $GITHUB_STEP_SUMMARY
echo "Pull request is not merged. Exiting."
echo "merged=false" >> $GITHUB_OUTPUT
exit 1
else
echo "### ✅ Pull Request Merged" >> $GITHUB_STEP_SUMMARY
echo "merged=true" >> $GITHUB_OUTPUT
fi
shell: bash

get-labels:
needs: check-merged
runs-on: ubuntu-latest
outputs:
version_type: ${{ steps.get.outputs.version_type }}
steps:
# This step requires that the repo has 3 types of version bump labels. Make any adjustments as
# needed to ensure that this step accurately parses the bump type.
# - version:patch
# - version:minor
# - version:major
- name: Get labels
id: get
run: |
LABELS="${{ join(github.event.pull_request.labels.*.name, ' ') }}"
VERSION_LABELS=$(echo $LABELS | tr ' ' '\n' | grep -E '^version-(patch|minor|major)$' || true)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other change here is to change version:* to version-* since you use a slightly different label format.

LABELS_COUNT=$(echo "$VERSION_LABELS" | wc -w)

if [[ "$LABELS_COUNT" -ne 1 ]]; then
echo "### ❌ Version Label Error" >> $GITHUB_STEP_SUMMARY
echo "Exactly one version label is required. Exiting."
exit 1
fi

VERSION_TYPE=$(echo "$VERSION_LABELS" | sed 's/^version://')
echo "version_type=$VERSION_TYPE" >> $GITHUB_OUTPUT
echo "$VERSION_TYPE" > version.txt

echo "### ✅ Valid Version Label" >> $GITHUB_STEP_SUMMARY
echo "Version label is valid. Version type: $VERSION_TYPE."
shell: bash

- name: Archive version
uses: actions/upload-artifact@v3
with:
name: 'version-${{ github.run_id }}'
path: version.txt

- name: Summarize version archiving
run: |
echo "### ✅ Version File Archived" >> $GITHUB_STEP_SUMMARY
echo "The version type `version.txt` has been archived under the name `version-${{ github.run_id }}`."
shell: bash