Skip to content

Commit 62b92f8

Browse files
author
Rundeck CI
committed
Add HEAD fallback
1 parent 5131fb4 commit 62b92f8

File tree

2 files changed

+94
-19
lines changed

2 files changed

+94
-19
lines changed

README.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ cat docs/history/5_x/draft.md
167167
npm run notes -- --milestone=5.17.0
168168
```
169169

170+
**Tag Detection:**
171+
- If the tag exists (e.g., `v5.17.0`), draft mode uses the exact tag comparison
172+
- If the tag doesn't exist yet, draft mode automatically uses `HEAD` to preview what will be in the release
173+
- You'll see: "Warning: Tag 5.17.0 not found, using HEAD for preview"
174+
- This allows you to preview release notes before creating the tag
175+
170176
## What the Script Does
171177

172178
When you run `npm run notes -- --milestone=5.17.0`, it will:
@@ -191,19 +197,25 @@ When you run `npm run notes -- --milestone=5.17.0`, it will:
191197
### Self-Hosted Release Process
192198

193199
```bash
194-
# 1. Generate draft for review
200+
# 1. Generate draft for review (before tagging)
201+
# If tag doesn't exist yet, uses HEAD for preview
195202
npm run notes:draft -- --milestone=5.17.0
196203

197204
# 2. Review the generated draft
198205
code docs/history/5_x/draft.md
199206

200-
# 3. Generate final release notes (updates all configs)
207+
# 3. Create the version tag
208+
git tag v5.17.0
209+
git push origin v5.17.0
210+
211+
# 4. Generate final release notes (updates all configs)
212+
# Now uses the exact tag for accurate PR detection
201213
npm run notes -- --milestone=5.17.0
202214

203-
# 4. Edit the generated file for dates, overview, etc.
215+
# 5. Edit the generated file for dates, overview, etc.
204216
code docs/history/5_x/version-5.17.0.md
205217

206-
# 5. Commit all changes
218+
# 6. Commit all changes
207219
git add docs/history/5_x/version-5.17.0.md
208220
git add docs/.vuepress/sidebar-menus/history.ts
209221
git add docs/.vuepress/navbar-menus/about.js
@@ -214,6 +226,8 @@ git commit -m "Release notes for 5.17.0"
214226
git push
215227
```
216228

229+
**Note:** You can preview with draft mode before creating the tag. Draft mode will use HEAD if the tag doesn't exist yet.
230+
217231
## SaaS Development Updates Feed
218232

219233
For generating RSS/Atom feeds and markdown pages showing recent PRs deployed to the SaaS platform (but not yet in self-hosted releases), see [PR-FEED-README.md](./PR-FEED-README.md).
@@ -228,16 +242,26 @@ The feed date range is automatically updated when you create release notes - no
228242

229243
## Troubleshooting Release Notes
230244

231-
### "Tags for versions X...Y not found"
245+
### "Tag X.Y.Z not found" Warning or Error
246+
247+
**In Draft Mode:**
248+
- Shows warning: "Tag 5.18.0 not found, using HEAD for preview"
249+
- Uses HEAD (main branch) to preview PRs
250+
- This is normal before the tag is created
251+
252+
**In Final Mode:**
253+
- Shows error: "Tag 5.18.0 not found. Create the tag first or use --draft mode."
254+
- Creates a placeholder file with minimal content
255+
- Re-run after creating the tag to populate with actual PRs
232256

233-
**Cause**: Tag doesn't exist in the repository or uses different naming.
257+
**Solution:**
258+
1. Use draft mode to preview: `npm run notes:draft -- --milestone=5.18.0`
259+
2. Create the tag when ready: `git tag v5.18.0 && git push origin v5.18.0`
260+
3. Generate final notes: `npm run notes -- --milestone=5.18.0`
234261

235-
**Solution**:
236-
- For `docs` and `ansible-plugin` repos: This is normal (they don't use version tags)
237-
- For main repos: Verify tags exist:
238-
```bash
239-
git ls-remote --tags https://github.com/rundeck/rundeck | grep 5.17
240-
```
262+
**For repo-specific warnings** (`docs`, `ansible-plugin`):
263+
- This is normal - these repos don't use version tags
264+
- They'll be skipped gracefully
241265

242266
### "GH_API_TOKEN environment variable is not set"
243267

docs/.vuepress/notes.mjs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,59 @@ async function main() {
6464
console.log('=== Rundeck Release Notes Generator ===\n');
6565
console.log(`Comparing versions: ${fromVersion}${toVersion}\n`);
6666

67+
// Check if toVersion tag exists by attempting to fetch from main repos
68+
const gh = new Octokit({ auth: process.env.GH_API_TOKEN });
69+
let tagExists = false;
70+
let useHead = false;
71+
72+
// Try to find the tag in rundeck repo (main repo)
73+
const tagFormats = [`v${toVersion}`, toVersion, `V${toVersion}`];
74+
for (const tag of tagFormats) {
75+
try {
76+
await gh.rest.repos.getReleaseByTag({
77+
owner: 'rundeck',
78+
repo: 'rundeck',
79+
tag: tag
80+
});
81+
tagExists = true;
82+
break;
83+
} catch (error) {
84+
if (error.status !== 404) {
85+
// Some other error, try git refs
86+
try {
87+
await gh.rest.git.getRef({
88+
owner: 'rundeck',
89+
repo: 'rundeck',
90+
ref: `tags/${tag}`
91+
});
92+
tagExists = true;
93+
break;
94+
} catch (refError) {
95+
// Continue to next format
96+
}
97+
}
98+
}
99+
}
100+
101+
// Determine behavior based on tag existence and mode
102+
if (!tagExists) {
103+
if (argv.draft) {
104+
console.log(`\nWarning: Tag ${toVersion} not found, using HEAD for preview\n`);
105+
useHead = true;
106+
} else {
107+
console.error(`\nERROR: Tag ${toVersion} not found.`);
108+
console.error(` Create the tag first or use --draft mode to preview with HEAD.\n`);
109+
console.log(`Continuing with empty results to create placeholder file...\n`);
110+
// Continue execution but with empty results
111+
}
112+
}
113+
67114
const context = {};
68-
context.core = await getRepoData({ repo: 'rundeck', owner: 'rundeck' }, fromVersion, toVersion, ['release-notes/include']);
69-
context.enterprise = await getRepoData({ repo: 'rundeckpro', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include']);
70-
context.docs = await getRepoData({ repo: 'docs', owner: 'rundeck' }, fromVersion, toVersion, []); // No label filtering for docs (need all PRs for contributors)
71-
context.ansible = await getRepoData({ repo: 'ansible-plugin', owner: 'rundeck-plugins' }, fromVersion, toVersion, ['release-notes/include']);
72-
context.runner = await getRepoData({ repo: 'sidecar', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include']);
115+
context.core = await getRepoData({ repo: 'rundeck', owner: 'rundeck' }, fromVersion, toVersion, ['release-notes/include'], useHead);
116+
context.enterprise = await getRepoData({ repo: 'rundeckpro', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include'], useHead);
117+
context.docs = await getRepoData({ repo: 'docs', owner: 'rundeck' }, fromVersion, toVersion, [], useHead); // No label filtering for docs (need all PRs for contributors)
118+
context.ansible = await getRepoData({ repo: 'ansible-plugin', owner: 'rundeck-plugins' }, fromVersion, toVersion, ['release-notes/include'], useHead);
119+
context.runner = await getRepoData({ repo: 'sidecar', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include'], useHead);
73120
context.contributors = { ...context.core.contributors, ...context.docs.contributors, ...context.ansible.contributors };
74121

75122
context.version = new RundeckVersion({ versionString: argv.milestone });
@@ -188,12 +235,15 @@ function updateNavbarReleaseLink(version) {
188235
}
189236
}
190237

191-
async function getRepoData(repo, fromVersion, toVersion, includeLabels) {
238+
async function getRepoData(repo, fromVersion, toVersion, includeLabels, useHead = false) {
192239
const gh = new Octokit({ auth: process.env.GH_API_TOKEN });
193240

194241
console.log(`Fetching PRs from ${repo.owner}/${repo.repo}...`);
195242

196243
try {
244+
// Determine the head reference
245+
const headRef = useHead ? 'main' : null;
246+
197247
// Fetch PRs between tags using shared utility
198248
const pulls = await fetchPRsBetweenTags(
199249
gh,
@@ -202,7 +252,8 @@ async function getRepoData(repo, fromVersion, toVersion, includeLabels) {
202252
fromVersion,
203253
toVersion,
204254
includeLabels,
205-
excludeUsernames // Use excludeUsernames as exclude labels (though these are for contributors)
255+
excludeUsernames, // Use excludeUsernames as exclude labels (though these are for contributors)
256+
headRef
206257
);
207258

208259
// Extract contributors (excluding bots and internal users)

0 commit comments

Comments
 (0)