-
Notifications
You must be signed in to change notification settings - Fork 68
ci: Add workflow for tagging stable commit #593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| # 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: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
| branches: | ||
| - main | ||
| # Allow manual trigger from Actions UI | ||
| workflow_dispatch: | ||
| schedule: | ||
| - cron: '0 0 * * MON,THU' # Runs on Tuesdays and Thursdays at midnight UTC | ||
|
|
||
| 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For debugging purposes I'd suggest to run |
||
|
|
||
| # 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: | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment not accurate |
||
| const channelRaw = lines.slice(headerIdx + 1) | ||
| .find(l => l.includes('/stable:')); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This finds the first line that has "/stable" in it. Can we assume that this is the correct stable release though, can we rely on the ordering? When I run snap info microceph I get So here the first line with squid/stable is indeed correct. Can we rely on that ordering though? The other issue I see here is that we're only handling the /stable releases in the main branch (ie. the latest major release). It would be great if we could also auto-tag other stable releases -- at the moment this would be squid, reef, quincy. Those would correspond to the branches main, reef and quincy respectively. Maybe the workflow could loop through all the foo/stable channels, exclude the one named "latest/stable" and look to tag in the main and named branches. |
||
| 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; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is codename here referring to the release channel name ? (like |
||
|
|
||
| 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}`); | ||
|
sabaini marked this conversation as resolved.
|
||
|
|
||
| # Verify commit exists in the repo and print commit message first line | ||
| - name: Verify commit exists | ||
| id: verify | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| 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 | ||
|
sabaini marked this conversation as resolved.
|
||
| } | ||
| ); | ||
| 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}"`); | ||
| core.setOutput('full_sha', hit.sha); // Output full SHA | ||
| } 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: | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| script: | | ||
| const commitSha = '${{ steps.verify.outputs.full_sha }}'; | ||
| const codeName = '${{ steps.snap.outputs.codeName }}'; | ||
| const version = '${{ steps.snap.outputs.version }}'; | ||
| const stableTag = `v${version}+${codeName}`; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So from what I've read above, if you use This has a slight problem that the tag will change everytime the underlying ceph point release changes. for example: in future the tag could become: Now since the tag is changing based on ceph-release, one of us would have to manually go and pull a new version on the RTD dashboard based on the new tag. I propose we do not use the full semantic version but just the constant bit (something like |
||
| 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.`); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment not accurate