Skip to content
Open
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
163 changes: 163 additions & 0 deletions .github/workflows/tag-stable-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# This workflow runs biweekly

name: Tag stable MicroCeph commit

# Controls when the action will run. Workflow runs when there is a new stable channel
# promoted on Snapcraft
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch: null
# schedule:
# - cron: '0 0 * * MON,THU' # Runs biweekly on Tuesdays and Thursdays
jobs:
tag-stable-commit:
# The type of runner that the job will run on
runs-on: ubuntu-latest
permissions:
contents: write # Needed for creating tags
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Install the MicroCeph snap
- name: Install MicroCeph snap
run: |
sudo snap install microceph
# Find the first name under "channels:" that includes "/stable:"
# and parse <code name>, <release version> and <commit ID>
- name: Extract channel information
id: snap
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
// Run `snap info microceph`
const info = execSync('snap info microceph', { encoding: 'utf-8' });
const lines = info.split('\n');
// Find the "channels:" header (ignoring indentation)
const headerIdx = lines.findIndex(l => l.trim().startsWith('channels:'));
if (headerIdx === -1) {
core.setFailed('Could not find "channels:" in snap info output');
return;
}
// Get the first non-empty channel line after the header
const channelRaw = lines.slice(headerIdx + 1)
.find(l => l.includes('/stable:'));
if (!channelRaw) {
core.setFailed('Could not find a "/stable:" channel line');
return;
}
core.info(`Channel line: "${channelRaw}"`);
// Parse version, and commit ID
const m = channelRaw.match(
/^\s*([a-z]+)\/stable:\s+([0-9.]+)\+snap([a-f0-9]+)\s/
);
if (!m) {
core.setFailed('Failed to parse channel line');
return;
}
const [, codeName, version, commit] = m;

const minCodeNameLength = 1; // At least 1 char
const minVersionLength = 6; // e.g. '19.2.0' or more
const minCommitLength= 7; // typical short git commit hash length

// Add minimum length requirement to validate output variables
if (!codeName || codeName.length < minCodeNameLength) {
core.setFailed(`Invalid codeName: "${codeName}"`);
return;
}
if (!version || version.length < minVersionLength) {
core.setFailed(`Invalid version: "${version}"`);
return;
}
if (!commit || commit.length < minCommitLength) {
core.setFailed(`Invalid commit: "${commit}"`);
return;
}

core.setOutput('codeName', codeName);
core.setOutput('version', version);
core.setOutput('commit', commit);
core.info(`codeName=${codeName}`);
core.info(`version=${version}`);
core.info(`commit=${commit}`);

# Verify commit exists in the repo and print commit message first line
- name: Verify commit exists
uses: actions/github-script@v7
with:
script: |
const target = '${{ steps.snap.outputs.commit }}'.slice(0, 7); // 7-char prefix
core.info(`Looking for a commit starting with "${target}" ...`);
const commits = await github.paginate(
github.rest.repos.listCommits,
{
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
}
);
const hit = commits.find(c => c.sha.startsWith(target));
if (hit) {
core.info(`Found commit: ${hit.sha} - ${hit.html_url}`);
// Print first line of the commit message
const firstLine = hit.commit.message.split('\n')[0];
core.info(`Commit message first line: "${firstLine}"`);
} else {
core.setFailed(`No commit starting with "${target}" found in the repository`);
}
# Create or update tag pointing to the verified commit
# If the tag doesn't exist, create it
# If the tag exists, but it points to a different commit, update it (move it forward)
# If it already exists but points to the correct commit, do nothing
- name: Create or update stable tag for verified commit
uses: actions/github-script@v7
with:
script: |
const commitSha = '${{ steps.snap.outputs.commit }}';
const codeName = '${{ steps.snap.outputs.codeName }}';
const version = '${{ steps.snap.outputs.version }}';
const stableTag = `v${version}+${codeName}`;
core.info(`Proposed stable tag: ${stableTag}`);

// Get existing tags
const tags = await github.paginate(
github.rest.repos.listTags,
{
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100
}
);

const existingTag = tags.find(t => t.name === stableTag);

if (existingTag) {
core.info(`Tag "${stableTag}" already exists.`);
if (existingTag.commit.sha === commitSha) {
core.info(`It already points to the correct commit (${commitSha}). Nothing to do.`);
return;
} else {
core.info(`Tag "${stableTag}" points to a different commit (${existingTag.commit.sha}). Updating to ${commitSha}...`);
await github.rest.git.updateRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `tags/${stableTag}`,
sha: commitSha,
force: true
});
core.info(`Tag "${stableTag}" updated to point to ${commitSha}.`);
return;
}
}

// Create tag if it doesn't exist
core.info(`Creating new tag "${stableTag}" pointing to commit ${commitSha}`);
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `refs/tags/${stableTag}`,
sha: commitSha
});
core.info(`Tag "${stableTag}" created successfully.`);

Loading