Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion docs/.vuepress/navbar-menus/about.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export default [
},
{
text: 'Release Notes',
link: '/history/5_x/version-5.18.0.md'
link: '/history/5_x/version-5.19.0.md'
}
]
69 changes: 55 additions & 14 deletions docs/.vuepress/notes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,16 @@ async function main() {
console.log(`Comparing versions: ${fromVersion} → ${toVersion}\n`);

// Check if toVersion tag exists by attempting to fetch from main repos
const gh = new Octokit({ auth: process.env.GH_API_TOKEN });
// Use a quiet Octokit instance to avoid noisy 404 logs during tag detection
const gh = new Octokit({
auth: process.env.GH_API_TOKEN,
log: {
debug: () => {},
info: () => {},
warn: () => {},
error: () => {}
}
});
let tagExists = false;
let useHead = false;

Expand All @@ -79,6 +88,7 @@ async function main() {
tag: tag
});
tagExists = true;
console.log(`✓ Found release tag: ${tag}\n`);
break;
} catch (error) {
if (error.status !== 404) {
Expand All @@ -90,6 +100,7 @@ async function main() {
ref: `tags/${tag}`
});
tagExists = true;
console.log(`✓ Found git tag: ${tag}\n`);
break;
} catch (refError) {
// Continue to next format
Expand All @@ -101,22 +112,34 @@ async function main() {
// Determine behavior based on tag existence and mode
if (!tagExists) {
if (argv.draft) {
console.log(`\nWarning: Tag ${toVersion} not found, using HEAD for preview\n`);
console.log(` Tag ${toVersion} not found, using HEAD for preview\n`);
useHead = true;
} else {
console.error(`\nERROR: Tag ${toVersion} not found.`);
console.error(` Create the tag first or use --draft mode to preview with HEAD.\n`);
console.log(`Continuing with empty results to create placeholder file...\n`);
// Continue execution but with empty results
console.log(`⚠ Tag ${toVersion} not found - creating placeholder file without PR data`);
console.log(` Tip: Use --draft mode to preview with HEAD, or create the tag first.\n`);
// Continue execution but skip PR fetching
}
}

const context = {};
context.core = await getRepoData({ repo: 'rundeck', owner: 'rundeck' }, fromVersion, toVersion, ['release-notes/include'], useHead);
context.enterprise = await getRepoData({ repo: 'rundeckpro', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include'], useHead);
context.docs = await getRepoData({ repo: 'docs', owner: 'rundeck' }, fromVersion, toVersion, [], useHead); // No label filtering for docs (need all PRs for contributors)
context.ansible = await getRepoData({ repo: 'ansible-plugin', owner: 'rundeck-plugins' }, fromVersion, toVersion, ['release-notes/include'], useHead);
context.runner = await getRepoData({ repo: 'sidecar', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include'], useHead);

// Skip PR fetching if tag doesn't exist and not in draft mode
const skipPRs = !tagExists && !useHead;

if (skipPRs) {
console.log('Skipping PR fetching (tag not found, not in draft mode)\n');
context.core = { contributors: {}, pulls: [] };
context.enterprise = { contributors: {}, pulls: [] };
context.docs = { contributors: {}, pulls: [] };
context.ansible = { contributors: {}, pulls: [] };
context.runner = { contributors: {}, pulls: [] };
} else {
context.core = await getRepoData({ repo: 'rundeck', owner: 'rundeck' }, fromVersion, toVersion, ['release-notes/include'], useHead);
context.enterprise = await getRepoData({ repo: 'rundeckpro', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include'], useHead);
context.docs = await getRepoData({ repo: 'docs', owner: 'rundeck' }, fromVersion, toVersion, [], useHead); // No label filtering for docs (need all PRs for contributors)
context.ansible = await getRepoData({ repo: 'ansible-plugin', owner: 'rundeck-plugins' }, fromVersion, toVersion, ['release-notes/include'], useHead);
context.runner = await getRepoData({ repo: 'sidecar', owner: 'rundeckpro' }, fromVersion, toVersion, ['release-notes/include'], useHead);
}
context.contributors = { ...context.core.contributors, ...context.docs.contributors, ...context.ansible.contributors };

context.version = new RundeckVersion({ versionString: argv.milestone });
Expand Down Expand Up @@ -155,13 +178,22 @@ async function main() {

// Only run update functions if not a draft
if (!argv.draft) {
//Turning off docsearch update for version specific page
//updateDocsearchVersion(argv.milestone);
console.log('\n=== Updating Configuration Files ===\n');
// Turning off docsearch update for version specific page
// updateDocsearchVersion(argv.milestone);
updateSetupJs(argv.milestone);
addSidebarVersion(argv.milestone);
updateLatestReleaseLink(argv.milestone);
updateNavbarReleaseLink(argv.milestone);
updatePRFeedConfig(argv.milestone);

console.log('\n✓ Successfully generated release notes and updated all configuration files!');
console.log(` File: ${outPath}`);
if (!tagExists && !useHead) {
console.log('\n Note: PR data not included (tag not found). Re-run after creating the tag to populate PR details.');
}
} else {
console.log(`\n✓ Draft release notes generated: ${outPath}`);
}
}

Expand Down Expand Up @@ -237,7 +269,16 @@ function updateNavbarReleaseLink(version) {
}

async function getRepoData(repo, fromVersion, toVersion, includeLabels, useHead = false) {
const gh = new Octokit({ auth: process.env.GH_API_TOKEN });
// Use quiet logging to avoid noisy 404 errors during tag format attempts
const gh = new Octokit({
auth: process.env.GH_API_TOKEN,
log: {
debug: () => {},
info: () => {},
warn: () => {},
error: () => {}
}
});

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

Expand Down
7 changes: 4 additions & 3 deletions docs/.vuepress/pr-feed-config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"lastSelfHostedRelease": {
"version": "5.18.0",
"lastSelfHostedDate": "2025-12-16",
"version": "5.19.0",
"lastSelfHostedDate": "2026-02-02",
"lastSaasRelease": "2025-01-26",
"lastSaasCut": "rba/5.19-RBA-20260122-adc13ef-8e5597d",
"description": "Last self-hosted GA release version and date"
"description": "Last self-hosted release version and date"
}
}
9 changes: 4 additions & 5 deletions docs/.vuepress/pr-utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export async function fetchPRsBetweenTags(octokit, owner, repo, fromVersion, toV
let baseTagUsed = null;
let headTagUsed = null;

// Try to find valid base tag
// Try to find valid base tag (silently try different formats)
for (const baseTag of baseTagFormats) {
for (const headTag of headTagFormats) {
try {
Expand All @@ -65,11 +65,11 @@ export async function fetchPRsBetweenTags(octokit, owner, repo, fromVersion, toV
});
baseTagUsed = baseTag;
headTagUsed = headTag;
console.log(` Found tags ${baseTag}...${headTag}, ${comparison.data.ahead_by} commits ahead`);
console.log(` Found tags ${baseTag}...${headTag}, ${comparison.data.ahead_by} commits ahead`);
break;
} catch (error) {
if (error.status === 404) {
continue; // Try next format
continue; // Try next format silently
}
throw error;
}
Expand All @@ -78,8 +78,7 @@ export async function fetchPRsBetweenTags(octokit, owner, repo, fromVersion, toV
}

if (!comparison) {
const errorMsg = `Tags for versions ${fromVersion}...${toVersion} not found in ${owner}/${repo}`;
console.warn(` Warning: ${errorMsg} - skipping this repository`);
console.log(` ⚠ Tags ${fromVersion}...${toVersion} not found - skipping ${owner}/${repo}`);
return [];
}

Expand Down
6 changes: 3 additions & 3 deletions docs/.vuepress/setup.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { BaseTransition } from "vue"

const RUNDECK_VERSION='5.18.0'
const RUNDECK_VERSION_FULL='5.18.0-SNAPSHOT'
const API_VERSION='56'
const RUNDECK_VERSION='5.19.0'
const RUNDECK_VERSION_FULL='5.19.0-SNAPSHOT'
const API_VERSION='57'
const API_DEP_REL='6.0.0'
const API_DEP_VER='17'
const API_MIN_VER='14'
Expand Down
7 changes: 6 additions & 1 deletion docs/.vuepress/sidebar-menus/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default [
{
text: 'Latest Release',
collapsible: false,
link: '/history/5_x/version-5.18.0.md',
link: '/history/5_x/version-5.19.0.md',
},
{
text: 'Recent Changes',
Expand Down Expand Up @@ -86,6 +86,11 @@ export default [
text: 'Version 5.x',
collapsible: true,
children: [
{
text: "5.19.0",
link: "https://docs.rundeck.com/5.19.0/"
},

{
text: "5.18.0",
link: "https://docs.rundeck.com/5.18.0/"
Expand Down
69 changes: 65 additions & 4 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3911,10 +3911,16 @@ To narrow down the result set over which the metrics will be calculated, you can

Paging parameters `max` and `offset` will have no effect on the result.

**Response**
**Additional Parameters (API v57+):**

* `useStats` (boolean): If `true`, use snapshot-based metrics from SCHEDULED_EXECUTION_STATS table. If `false` or not provided, use execution table query. When `useStats=true`, the `jobIdListFilter` parameter is required unless `groupByJob=true`.
* `groupByJob` (boolean): If `true` with `useStats=true`, returns metrics for all jobs in a single project (batch mode). The metrics query must be scoped to one project, either by using the project-specific endpoint (`/api/29/project/[PROJECT]/executions/metrics`) or by including a `project` query parameter when calling the global endpoint (`/api/29/executions/metrics`). Returns format: `{jobs: {uuid1: metrics, uuid2: metrics, ...}}`.
* `begin` (string): When using `useStats=true`, filter metrics to include only executions that completed on or after this date. Format: `yyyy-MM-ddTHH:mm:ssZ` (ISO8601).
* `end` (string): When using `useStats=true`, filter metrics to include only executions that completed on or before this date. Format: `yyyy-MM-ddTHH:mm:ssZ` (ISO8601).

**Response**

An object with `duration` entry containing duration stats, and a `total` entry with total executions.
When `groupByJob` is not used, the response is an object with `duration` entry containing duration stats, and a `total` entry with total executions:

``` json
{
Expand All @@ -3927,6 +3933,33 @@ An object with `duration` entry containing duration stats, and a `total` entry w
}
```

When `groupByJob=true` with `useStats=true` (API v57+), the response format is:

``` json
{
"jobs": {
"uuid1": {
"total": 100,
"succeeded": 95,
"failed": 5,
"duration": {
"average": "5s"
},
...
},
"uuid2": {
"total": 50,
"succeeded": 48,
"failed": 2,
"duration": {
"average": "3s"
},
...
}
}
}
```


### Execution State

Expand Down Expand Up @@ -6319,7 +6352,26 @@ Same response as [Setup SCM Plugin for a Project](#setup-scm-plugin-for-a-projec
"service": "NodeExecutor",
"title": "Kubernetes / Pods / Node Executor",
"iconUrl": "...",
"providerMetadata": { }
"providerMetadata": {
"groupBy": "Kubernetes",
"groupIconUrl": "/path/to/kubernetes-icon.svg"
}
},
{
"artifactName": "aws-vm-plugin",
"author": "Rundeck",
"builtin": false,
"description": "AWS VM management plugin",
"id": "abc123def456",
"name": "AwsVmStartPlugin",
"pluginVersion": "2.0.0",
"service": "WorkflowStep",
"title": "AWS VM Start",
"iconUrl": "...",
"providerMetadata": {
"groupBy": "AWS VM",
"groupIconUrl": "/path/to/aws-icon.svg"
}
},
{
"artifactName": "py-winrm-plugin",
Expand All @@ -6340,6 +6392,8 @@ Same response as [Setup SCM Plugin for a Project](#setup-scm-plugin-for-a-projec

* `iconUrl` - URL to icon file for the plugin if present. **since V40**
* `providerMetadata` - Map of metadata about the plugin if present. **since V40**
* `groupBy` - The group name for the plugin, used for UI grouping. Plugins with the same `groupBy` value will be grouped together in the UI. **since V57**
* `groupIconUrl` - The icon URL for the plugin group. This may be explicitly defined for the group or automatically determined from the first plugin in the group. **since V57**

### Get Plugin Detail

Expand All @@ -6361,7 +6415,10 @@ Since: v49
"targetHostCompatibility": "all",
"ver": null,
"id": "d36b17dfae7b",
"providerMetadata": {},
"providerMetadata": {
"groupBy": "MyGroup",
"groupIconUrl": "/path/to/group-icon.svg"
},
"dynamicProps": null,
"thirdPartyDependencies": null,
"name": "<provider-name>",
Expand Down Expand Up @@ -6395,6 +6452,10 @@ Since: v49
}
```

The `providerMetadata` object may contain:
* `groupBy` - The group name for the plugin, used for UI grouping. **since V57**
* `groupIconUrl` - The icon URL for the plugin group. **since V57**

## Webhooks

### List Project Webhooks
Expand Down
14 changes: 14 additions & 0 deletions docs/api/rundeck-api-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ Changes introduced by API Version number:
API versions below `{{$apiDepVersion}}` are *deprecated*. Clients using earlier versions should upgrade to use `{{$apiDepVersion}}` as the minimum version before release `{{ $apiDepRelease }}` to avoid errors.
:::

### Version 57

* Updated Endpoints:
* [`GET /api/V/plugin/list`][GET /api/V/plugin/list] - Plugin list response `providerMetadata` now includes `groupBy` and `groupIconUrl` fields for plugin UI grouping
* [`GET /api/V/plugin/detail/[SERVICE]/[PROVIDER]`][GET /api/V/plugin/detail/\[SERVICE\]/\[PROVIDER\]] - Plugin detail response `providerMetadata` now includes `groupBy` and `groupIconUrl` fields for plugin UI grouping
* [`GET /api/V/executions/metrics`][/api/V/executions/metrics]
* Added `useStats` parameter: if `true`, use snapshot-based metrics from `SCHEDULED_EXECUTION_STATS` table. If `false` or not provided, use execution table query.
* Added `groupByJob` parameter: if `true` with `useStats=true`, returns metrics for all jobs in the project (batch mode). Requires `project` parameter.
* Added `begin` and `end` parameters for date range filtering when using `useStats=true`.
* [`GET /api/V/project/[PROJECT]/executions/metrics`][/api/V/project/\[PROJECT\]/executions/metrics]
* Added `useStats` parameter: if `true`, use snapshot-based metrics from `SCHEDULED_EXECUTION_STATS` table. If `false` or not provided, use execution table query.
* Added `groupByJob` parameter: if `true` with `useStats=true`, returns metrics for all jobs in the project (batch mode).
* Added `begin` and `end` parameters for date range filtering when using `useStats=true`.

### Version 56

* Updated Endpoints:
Expand Down
Loading