Skip to content

Auto Release

Auto Release #75

Workflow file for this run

name: Auto Release
on:
schedule:
# Run every 24 hours at midnight UTC
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
version:
description: 'Version tag to create (optional, defaults to date-based)'
required: false
default: ''
jobs:
check-and-release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest release
id: latest_release
uses: actions/github-script@v7
with:
script: |
const releases = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 1
});
if (releases.data.length > 0) {
console.log('Latest release found:', releases.data[0].tag_name);
return releases.data[0].tag_name;
} else {
console.log('No previous releases found');
return null;
}
- name: Determine if release is needed
id: check_changes
uses: actions/github-script@v7
with:
script: |
const latestRelease = '${{ steps.latest_release.outputs.result }}';
let commitCount = 0;
if (latestRelease && latestRelease !== 'null') {
// Compare against the latest release tag
try {
const compare = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: latestRelease,
head: 'HEAD'
});
commitCount = compare.data.ahead_by;
console.log('Commits ahead of last release:', commitCount);
if (commitCount > 0) {
const commits = compare.data.commits.slice(0, 5).map(c => ` - ${c.commit.message.split('\n')[0]}`).join('\n');
core.setOutput('changes_summary', `${commitCount} new commit(s) since ${latestRelease}:\n${commits}`);
}
} catch (error) {
console.log('Could not compare commits, treating as no changes:', error.message);
commitCount = 0;
}
} else {
// No previous release - check all commits
const commits = await github.rest.repos.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
});
commitCount = commits.data.length;
console.log('Total commits (no previous release):', commitCount);
if (commitCount > 0) {
const firstCommits = commits.data.slice(0, 5).map(c => ` - ${c.commit.message.split('\n')[0]}`).join('\n');
core.setOutput('changes_summary', `${commitCount} commit(s) in repository (first release):\n${firstCommits}`);
}
}
core.setOutput('needs_release', commitCount > 0 ? 'true' : 'false');
core.setOutput('commit_count', commitCount);
- name: Create release
if: steps.check_changes.outputs.needs_release == 'true'
id: create_release
uses: actions/github-script@v7
with:
script: |
// Get version from input or use date-based version
const manualVersion = '${{ github.event.inputs.version }}';
const version = manualVersion || new Date().toISOString().split('T')[0];
// Validate version format
const versionPattern = /^[a-zA-Z0-9._-]+$/;
if (manualVersion && !versionPattern.test(manualVersion)) {
throw new Error('Invalid version format: must match pattern [a-zA-Z0-9._-]');
}
const changesSummary = '${{ steps.check_changes.outputs.changes_summary }}';
console.log('Creating release with version:', version);
console.log('Changes:', changesSummary);
// Check if release already exists first
const existing = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
});
const existingRelease = existing.data.find(r => r.tag_name === version);
if (existingRelease) {
console.log('Release with this tag already exists');
core.setOutput('release_url', existingRelease.html_url);
core.setOutput('release_id', existingRelease.id);
return;
}
// Then create the release
const release = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: version,
name: `Release ${version}`,
body: `## Changes since last release\n\n${changesSummary}\n\n---\n\n*Auto-generated release on ${new Date().toISOString()}*`,
draft: false,
prerelease: false
});
console.log('Release created:', release.data.html_url);
core.setOutput('release_url', release.data.html_url);
core.setOutput('release_id', release.data.id);
- name: Summary
if: always()
uses: actions/github-script@v7
with:
script: |
const needsRelease = '${{ steps.check_changes.outputs.needs_release }}';
const releaseUrl = '${{ steps.create_release.outputs.release_url }}';
const commitCount = '${{ steps.check_changes.outputs.commit_count }}';
if (needsRelease === 'true' && releaseUrl) {
console.log('✅ Release created successfully!');
console.log(' Commits:', commitCount);
console.log(' URL:', releaseUrl);
} else if (needsRelease === 'true' && !releaseUrl) {
console.log('⚠️ Changes detected but release already exists');
} else {
console.log('ℹ️ No changes since last release, skipping release');
}