Skip to content
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e20cf12
Add docker-build-and-push
nuc Jul 16, 2025
5d98b22
Put back the old one for now
nuc Jul 16, 2025
a531a15
Pass build_args to the build
nuc Jul 16, 2025
d0e86a3
Pass build_args as secret
nuc Jul 16, 2025
9125540
Define secrets in the workflow
nuc Jul 16, 2025
554bf6d
docker-build-push and create-release-pr
marek-saji Jul 22, 2025
36dfd6a
Make actionlint happy
marek-saji Jul 22, 2025
6ec1e2d
Don’t use deprecated :: commands
marek-saji Jul 22, 2025
ae07de7
Build without any tags
marek-saji Jul 22, 2025
97e4dd2
Language
marek-saji Jul 22, 2025
a700b2c
fixup! docker-build-push and create-release-pr
marek-saji Jul 22, 2025
541faab
docker-build-push: Define version_change output
marek-saji Jul 22, 2025
4ebfda3
fixup! docker-build-push and create-release-pr
marek-saji Jul 22, 2025
cd3e673
Typo
marek-saji Jul 22, 2025
5924c1a
prettier -w .
marek-saji Jul 22, 2025
917334c
Use ref-comment-in-commit action
marek-saji Jul 22, 2025
02ea9a4
Ignore VSCode config
marek-saji Jul 22, 2025
c3f287e
Revert "Don’t use deprecated :: commands"
marek-saji Jul 22, 2025
c74375a
Validate required inputs
marek-saji Jul 22, 2025
7517d37
create-release-pr: Pretty white space in CHANGELOG
marek-saji Jul 28, 2025
54ab96c
Merge remote-tracking branch 'origin/v1' into new-actions-for-buildin…
marek-saji Oct 1, 2025
b0f2c0e
Merge remote-tracking branch 'origin/v1' into HEAD
marek-saji Oct 6, 2025
fae8fa2
feat: Start adjusting workflows to new vision
marek-saji Oct 1, 2025
4475f0f
Update used actions
marek-saji Oct 1, 2025
ca3c806
feat(ci): Run npm audit signatures
marek-saji Oct 1, 2025
38e0ca4
feat(ci): Output package-manager
marek-saji Oct 2, 2025
cc15470
feat(create-release): Use semantic-release
marek-saji Oct 2, 2025
dcc6de6
feat(docker-build-push): Push to all registries in one go
marek-saji Oct 2, 2025
2ce840e
fixup! feat: Start adjusting workflows to new vision
marek-saji Oct 6, 2025
4962cdb
DEBUG: Use current branch for setup step
marek-saji Oct 6, 2025
307834e
fixup! feat(ci): Run npm audit signatures
marek-saji Oct 6, 2025
ca91c53
fixup! feat(create-release): Use semantic-release
marek-saji Oct 6, 2025
c53fc6b
fixup! feat(create-release): Use semantic-release
marek-saji Oct 6, 2025
d3f1208
chore: Kebab case for inputs
marek-saji Oct 6, 2025
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
1 change: 1 addition & 0 deletions .github/workflows/chromatic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:

if [ -z "${{ secrets.CHROMATIC_PROJECT_TOKEN }}" ]
then
# shellcheck disable=SC1111
echo "::error::Missing secret CHROMATIC_PROJECT_TOKEN. You can get it https://www.chromatic.com/start, then open your project and go to “Manage” → “Configure”."
exit_code=78
fi
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ jobs:
env:
ENV_VARS: ${{ secrets.env_vars }}
run: |
echo $ENV_VARS >> "$GITHUB_ENV"
echo "$ENV_VARS" >> "$GITHUB_ENV"

- name: Setup
uses: verkstedt/actions/setup@v1
Expand Down Expand Up @@ -320,7 +320,7 @@ jobs:
env:
ENV_VARS: ${{ secrets.env_vars }}
run: |
echo $ENV_VARS >> "$GITHUB_ENV"
echo "$ENV_VARS" >> "$GITHUB_ENV"
- name: Setup
uses: verkstedt/actions/setup@v1
with:
Expand Down
284 changes: 284 additions & 0 deletions .github/workflows/create-release-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
# Create Release PR
#
# Template to use with this workflow:
# https://github.com/verkstedt/.github/tree/main/workflow-templates/create-release-pr.yaml
#
# Creates a release PR with:
# - Bumped version in package.json (patch, minor, major, or prerelease)
# - CHANGELOG.md containing release notes since last release

name: Create Release PR

on:
workflow_call:
inputs:
release_type:
description: 'Type of release (major, minor, patch, or prerelease)'
type: string
default: 'patch'

jobs:
release:
name: 'Create Release PR'
runs-on: ubuntu-latest

permissions:
contents: write
pull-requests: write
issues: write

outputs:
old_version: ${{ steps.version_info.outputs.old_version }}
new_version: ${{ steps.version_info.outputs.new_version }}
pr_number: ${{ steps.create_pr.outputs.pull-request-number }}
pr_url: ${{ steps.create_pr.outputs.pull-request-url }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Get current version info
id: version_info
run: |
OLD_VERSION="$(jq -r '.version' package.json)"
echo "old_version=$OLD_VERSION" | tee -a "$GITHUB_OUTPUT"

OLD_VERSION_GIT_TAG="v$OLD_VERSION"
# Check if tag exists
if ! git ls-remote --tags origin "$OLD_VERSION_GIT_TAG" &>/dev/null
then
echo "::error::Previous version tag $OLD_VERSION_GIT_TAG not found." 2>&1
exit 65 # EX_DATAERR
fi
echo "old_version_git_tag=$OLD_VERSION_GIT_TAG" | tee -a "$GITHUB_OUTPUT"

- name: Bump version
id: bump_version
uses: actions/github-script@v7
with:
# Manipulating package.json instead of using `yarn version` to bump up
# the version, because `yarn` also wastefully run `yarn install`
script: |
const fs = require('fs');
const releaseType = ${{ toJson(inputs.release_type) }};

// Read package.json
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const oldVersion = packageJson.version;

let newVersion;
switch (releaseType) {
case 'major': {
const versionMatch = oldVersion.match(/^(\d+)\./);
if (!versionMatch) {
throw new Error(`Invalid version format for major bump: ${oldVersion}`);
}
const major = parseInt(versionMatch[1]);
newVersion = `${major + 1}.0.0`;
break;
}
case 'minor': {
const versionMatch = oldVersion.match(/^(\d+)\.(\d+)\./);
if (!versionMatch) {
throw new Error(`Invalid version format for minor bump: ${oldVersion}`);
}
const [, major, minor] = versionMatch;
newVersion = `${major}.${parseInt(minor) + 1}.0`;
break;
}
case 'patch': {
const versionMatch = oldVersion.match(/^(\d+)\.(\d+)\.(\d+)($|-|\+)/);
if (!versionMatch) {
throw new Error(`Invalid version format for patch bump: ${oldVersion}`);
}
const [, major, minor, patch] = versionMatch;
newVersion = `${major}.${minor}.${parseInt(patch) + 1}`;
break;
}
case 'prerelease': {
const versionMatch = oldVersion.match(/^(\d+)\.(\d+)\.(\d+)(?:-(\d+))?$/);
if (!versionMatch) {
throw new Error(`Invalid version format for prerelease bump: ${oldVersion}`);
}
let [, major, minor, patch, prerelease] = versionMatch;
prerelease = prerelease ? parseInt(prerelease) : null;
const newPrerelease = prerelease !== null ? prerelease + 1 : 0;
newVersion = `${major}.${minor}.${patch}-${newPrerelease}`;
break;
}
default:
throw new Error(`Invalid release type: ${releaseType}`);
}

// Update package.json
packageJson.version = newVersion;
fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2) + '\n');

core.setOutput('new_version', newVersion);
core.setOutput('new_version_git_tag', `v${newVersion}`);
core.setOutput('new_version_branch_name', `release/v${newVersion}`);

- name: Generate release notes
id: release_notes
uses: actions/github-script@v7
with:
script: |
const newVersion = ${{ toJson(steps.bump_version.outputs.new_version) }};
const newTag = ${{ toJson(steps.bump_version.outputs.new_version_git_tag) }};
const newBranchName = ${{ toJson(steps.bump_version.outputs.new_version_branch_name) }};
const previousTag = ${{ toJson(steps.version_info.outputs.old_version_git_tag) }};
const targetCommitish = context.sha;

// Generate release notes using GitHub API
const { data: releaseNotes } = await github.rest.repos.generateReleaseNotes({
owner: context.repo.owner,
repo: context.repo.repo,
// Note: This git tag is not created here. It will only be pushed
// in docker-build-and-push workflow after PR created by this
// workflow is merged.
tag_name: newTag,
target_commitish: targetCommitish,
previous_tag_name: previousTag
});

// Increase header levels by one
const changes = releaseNotes.body.replace(/^(#{1,5})\s/gm, '#$1 ');

core.setOutput('content', changes);

// Output includes link that compares old tag to new one, but new one will only be created
// after this PR is merged, so we’ll output also a patched version of the link
core.setOutput('content_draft', changes.replace(
new RegExp(`\.\.\.${newTag}`),
`\.\.\.${newBranchName}`
));

- name: Update or create CHANGELOG.md
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');

const newVersion = ${{ toJson(steps.bump_version.outputs.new_version) }};
const releaseNotes = ${{ toJson(steps.release_notes.outputs.content) }};

const newSectionContent = [
`## ${newVersion} <a id="user-content-${newVersion}" href="#user-content-${newVersion}">🔗</a>`,
'',
releaseNotes.trim(),
].join('\n');

let oldContent = ''
try {
oldContent = fs.readFileSync('CHANGELOG.md', 'utf8');
} catch {
// File doesn't exist, will create new one
}

const lines = oldContent.split('\n');
const headerLineIndex = lines.findIndex(line => line.match(/^# Changelog/));

let before = '';
let after = '';
if (headerLineIndex === -1) {
before = '# Changelog';
after = oldContent;
} else {
before = lines.slice(0, headerLineIndex + 1).join('\n');
after = lines.slice(headerLineIndex + 1).join('\n');
}

const newContent = [
before,
newSectionContent,
after,
]
.map(section => section.trim())
.join('\n\n')
.trim() + '\n';

fs.writeFileSync('CHANGELOG.md', newContent);

- name: Commit changes
id: commit
env:
BRANCH_NAME: ${{ steps.bump_version.outputs.new_version_branch_name }}
NEW_VERSION: ${{ steps.bump_version.outputs.new_version }}
RELEASE_NOTES: ${{ steps.release_notes.outputs.content }}
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"

echo "branch_name=$BRANCH_NAME" | tee -a "$GITHUB_OUTPUT"
git switch -c "$BRANCH_NAME"

git add package.json CHANGELOG.md
git commit -m "$NEW_VERSION" -m "$RELEASE_NOTES"
git push -u origin "$BRANCH_NAME"

- name: Create Pull Request
id: create_pr
uses: actions/github-script@v7
with:
script: |
const newVersion = ${{ toJson(steps.bump_version.outputs.new_version) }};
const branchName = ${{ toJson(steps.commit.outputs.branch_name) }};
const releaseNotes = ${{ toJson(steps.release_notes.outputs.content_draft) }};

// Create pull request
const { data: pr } = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Release ${newVersion}`,
head: branchName,
base: 'test-github-actions', // DEBUG TODO Change to main when ready
Copy link
Contributor

Choose a reason for hiding this comment

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

❗ Remember to change to main before merging.

body: `## Changes\n\n${releaseNotes}`,
draft: false
});

// Add labels
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: ['release', 'automated']
});

core.setOutput('pull-request-number', pr.number);
core.setOutput('pull-request-url', pr.html_url);

- name: Summary
env:
OLD_VERSION: ${{ steps.version_info.outputs.old_version }}
NEW_VERSION: ${{ steps.bump_version.outputs.new_version }}
RELEASE_TYPE: ${{ inputs.release_type }}
PR_NUMBER: ${{ steps.create_pr.outputs.pull-request-number }}
PR_URL: ${{ steps.create_pr.outputs.pull-request-url }}
CHANGES: ${{ steps.release_notes.outputs.content_draft }}
run: |
cat >> "$GITHUB_STEP_SUMMARY" << EOF
# 🚀 Release ${NEW_VERSION}

## Version Changes

- **Previous version:** \`${OLD_VERSION}\`
- **Release type:** \`${RELEASE_TYPE}\`
- **New version:** \`${NEW_VERSION}\`

## Pull Request

- [#${PR_NUMBER}](${PR_URL})

## Next Steps

1. Review and merge the pull request to complete the release
2. Merging will trigger workflow that will publish the new release

## Release Notes

${CHANGES}

EOF
Loading