Task - Release #6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Task - Release | |
on: | |
workflow_dispatch: | |
inputs: | |
version: | |
description: 'Release version' | |
required: true | |
default: '1.0.0' | |
title: | |
description: 'Title' | |
required: true | |
default: 'New Version' | |
changelog: | |
description: 'Changelog' | |
required: true | |
default: '- Several improvements' | |
issue: | |
description: 'Launcher issue' | |
required: true | |
default: -1 | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
cancel-in-progress: true | |
jobs: | |
check-tag: | |
name: Publish version | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Create tag | |
id: create_tag | |
run: | | |
# Check if the tag already exists in the remote repository | |
if git rev-parse "v${{ github.event.inputs.version }}" >/dev/null 2>&1; then | |
echo "Tag v${{ github.event.inputs.version }} already exists." | |
exit 1 | |
else | |
echo "Tag v${{ github.event.inputs.version }} not exists." | |
fi | |
prepare-files: | |
name: Prepare files for release | |
runs-on: ubuntu-latest | |
needs: [ check-tag ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Check branch and prepare SSH | |
run: | | |
if [[ "${{ github.ref_name }}" == release/* ]]; then | |
echo "Release branch." | |
else | |
echo "Not valid branch type." | |
exit 1 | |
fi | |
mkdir -p ~/.ssh | |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519 | |
chmod 600 ~/.ssh/id_ed25519 | |
ssh-keyscan github.com >> ~/.ssh/known_hosts | |
git remote set-url origin [email protected]:landamessenger/git-board-flow.git | |
- name: Set up Node.js 20 | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20.x' | |
- name: Update version | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const fs = require('fs'); | |
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); | |
packageJson.version = '${{ github.event.inputs.version }}'; | |
fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2)); | |
- name: Compile files | |
run: | | |
npm install | |
npm run build | |
- name: Commit updated package.json and dist directory | |
uses: EndBug/add-and-commit@v9 | |
with: | |
add: './dist/ ./package.json' | |
committer_name: GitHub Actions | |
committer_email: [email protected] | |
default_author: user_info | |
message: 'gh-action: updated compiled files and bumped version to ${{ github.event.inputs.version }}' | |
tag: | |
name: Publish version | |
runs-on: ubuntu-latest | |
needs: [ prepare-files ] | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Prepare SSH and create tag | |
run: | | |
mkdir -p ~/.ssh | |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519 | |
chmod 600 ~/.ssh/id_ed25519 | |
ssh-keyscan github.com >> ~/.ssh/known_hosts | |
git remote set-url origin [email protected]:landamessenger/git-board-flow.git | |
git pull origin | |
# Check if the tag already exists in the remote repository | |
if git rev-parse "v${{ github.event.inputs.version }}" >/dev/null 2>&1; then | |
echo "Tag v${{ github.event.inputs.version }} already exists." | |
else | |
# Create and push the new tag | |
git tag "v${{ github.event.inputs.version }}" | |
git push origin "v${{ github.event.inputs.version }}" | |
fi | |
- name: Create a release | |
id: create_release | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const version = "${{ github.event.inputs.version }}"; | |
const title = "${{ github.event.inputs.title }}"; | |
const changelog = "${{ github.event.inputs.changelog }}"; | |
const { data: release } = await github.rest.repos.createRelease({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
tag_name: `v${version}`, | |
name: `v${version} - ${title}`, | |
body: changelog, | |
draft: false, | |
prerelease: false, | |
}); | |
console.log(`Release created: ${release.html_url}`); | |
- name: Publish to GitHub Marketplace | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.REPO_PAT }} | |
script: | | |
const sourceTag = 'v${{ github.event.inputs.version }}'; | |
const targetTag = sourceTag.split('.')[0]; | |
async function findTag(tag) { | |
try { | |
const { data: foundTag } = await github.rest.git.getRef({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
ref: `tags/${tag}`, | |
}); | |
return foundTag; | |
} catch (err) { | |
if (err.status === 404) { | |
return null; | |
} | |
throw new Error(`Retrieving refs failed with the following error: ${err.message}`); | |
} | |
} | |
async function getTagSHA(tag) { | |
const foundTag = await findTag(tag); | |
if (!foundTag) { | |
throw new Error(`The '${tag}' tag does not exist in the remote repository`); | |
} | |
return foundTag.object.sha; | |
} | |
async function updateTag(sourceTag, targetTag) { | |
const sourceTagSHA = await getTagSHA(sourceTag); | |
const foundTargetTag = await findTag(targetTag); | |
const refName = `tags/${targetTag}`; | |
if (foundTargetTag) { | |
console.log(`Updating the '${targetTag}' tag to point to the '${sourceTag}' tag`); | |
await github.rest.git.updateRef({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
ref: refName, | |
sha: sourceTagSHA, | |
force: true, | |
}); | |
} else { | |
console.log(`Creating the '${targetTag}' tag from the '${sourceTag}' tag`); | |
await github.rest.git.createRef({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
ref: `refs/${refName}`, | |
sha: sourceTagSHA, | |
}); | |
} | |
} | |
async function updateRelease(sourceTag, targetTag) { | |
// Get the release associated with sourceTag | |
const { data: sourceRelease } = await github.rest.repos.getReleaseByTag({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
tag: sourceTag, | |
}); | |
console.log(`Found release for sourceTag '${sourceTag}': ${sourceRelease.name}`); | |
// Check if there is a release for targetTag | |
const { data: releases } = await github.rest.repos.listReleases({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
}); | |
const targetRelease = releases.find(r => r.tag_name === targetTag); | |
let targetReleaseId; | |
if (targetRelease) { | |
console.log(`Updating release for targetTag '${targetTag}'`); | |
// Update the target release with the content from the source release | |
await github.rest.repos.updateRelease({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
release_id: targetRelease.id, | |
name: sourceRelease.name, | |
body: sourceRelease.body, | |
draft: sourceRelease.draft, | |
prerelease: sourceRelease.prerelease, | |
}); | |
targetReleaseId = targetRelease.id; | |
} else { | |
console.log(`Creating new release for targetTag '${targetTag}'`); | |
// Create a new release for targetTag if it doesn't exist | |
const { data: newRelease } = await github.rest.repos.createRelease({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
tag_name: targetTag, | |
name: sourceRelease.name, | |
body: sourceRelease.body, | |
draft: sourceRelease.draft, | |
prerelease: sourceRelease.prerelease, | |
}); | |
targetReleaseId = newRelease.id; | |
} | |
} | |
await updateTag(sourceTag, targetTag); | |
await updateRelease(sourceTag, targetTag); | |
- name: Git Board - Deploy success notification | |
uses: ./ | |
if: ${{ success() }} | |
with: | |
single-action: 'deployed_action' | |
single-action-issue: '${{ github.event.inputs.issue }}' | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
github-token-personal: ${{ secrets.REPO_PAT }} |