Skip to content

Task - Release

Task - Release #6

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 }}