diff --git a/docs/.vuepress/navbar-menus/about.js b/docs/.vuepress/navbar-menus/about.js index b1ddd6fde..7765b8fb8 100644 --- a/docs/.vuepress/navbar-menus/about.js +++ b/docs/.vuepress/navbar-menus/about.js @@ -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' } ] diff --git a/docs/.vuepress/notes.mjs b/docs/.vuepress/notes.mjs index 9f444a1ca..e899673a9 100644 --- a/docs/.vuepress/notes.mjs +++ b/docs/.vuepress/notes.mjs @@ -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; @@ -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) { @@ -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 @@ -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 }); @@ -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}`); } } @@ -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}...`); diff --git a/docs/.vuepress/pr-feed-config.json b/docs/.vuepress/pr-feed-config.json index e5e08142d..d0966ca0b 100644 --- a/docs/.vuepress/pr-feed-config.json +++ b/docs/.vuepress/pr-feed-config.json @@ -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" } } diff --git a/docs/.vuepress/pr-utils.mjs b/docs/.vuepress/pr-utils.mjs index ad61b4f8a..0d4f75722 100644 --- a/docs/.vuepress/pr-utils.mjs +++ b/docs/.vuepress/pr-utils.mjs @@ -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 { @@ -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; } @@ -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 []; } diff --git a/docs/.vuepress/setup.js b/docs/.vuepress/setup.js index 1b08356fc..1348fb0b2 100644 --- a/docs/.vuepress/setup.js +++ b/docs/.vuepress/setup.js @@ -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' diff --git a/docs/.vuepress/sidebar-menus/history.ts b/docs/.vuepress/sidebar-menus/history.ts index b280def9c..b1f4b5260 100644 --- a/docs/.vuepress/sidebar-menus/history.ts +++ b/docs/.vuepress/sidebar-menus/history.ts @@ -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', @@ -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/" diff --git a/docs/api/index.md b/docs/api/index.md index 4439e01e4..02b3e856e 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -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 { @@ -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 @@ -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", @@ -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 @@ -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": "", @@ -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 diff --git a/docs/api/rundeck-api-versions.md b/docs/api/rundeck-api-versions.md index b8abcfc9e..d05dfe3c8 100644 --- a/docs/api/rundeck-api-versions.md +++ b/docs/api/rundeck-api-versions.md @@ -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: diff --git a/docs/history/5_x/version-5.19.0.md b/docs/history/5_x/version-5.19.0.md new file mode 100644 index 000000000..b440b9ad8 --- /dev/null +++ b/docs/history/5_x/version-5.19.0.md @@ -0,0 +1,91 @@ +--- + +title: "5.19.0 Release Notes" +date: 2026-02-02 +image: /images/chevron-logo-red-on-white.png +description: "Rundeck | Runbook Automation 5.19.0 release with Ansible output fixes, Vault timestamp corrections, extended AWS SSM timeouts, Azure storage security updates, and faster Job UI metrics." +feed: + enable: true + description: "Rundeck | Runbook Automation 5.19.0 release with Ansible output fixes, Vault timestamp corrections, extended AWS SSM timeouts, Azure storage security updates, and faster Job UI metrics." + +--- + +# 5.19.0 Release Notes + +## Overview + +This release focuses on stability, performance, and security improvements across the platform. Key updates include enhanced AWS SSM execution timeouts (up to 12 hours), significant Job UI Metrics performance optimizations, and fixes for Ansible workflow output handling and Vault timestamp issues. Security updates address multiple CVEs in the Azure Storage plugin and Docker image dependencies. + + + +## Runbook Automation Updates + +##### ::circle-dot:: Hashicorp Vault integration modification time issue + +Fixed an issue where Vault keys displayed incorrect modification and creation timestamps in Rundeck due to missing metadata. + +##### ::circle-dot:: Allow executions up to 12 hours for AWS SSM using AssumeRole + +Enhanced AWS SSM node executor to support execution durations up to 12 hours when using AssumeRole authentication, enabling longer-running operations for cross-account AWS deployments. The system now automatically validates and adjusts timeout values to ensure compliance with AWS service limits, preventing execution failures due to timeout configuration errors. + +##### ::circle-dot:: Bump Azure Storage Plugin version to 1.0.4 + +Bump aiohttp to 3.13.3 minimum for CVE-2025-69223, CVE-2025-69227, and CVE-2025-69228 + +##### ::circle-dot:: Implement performance optimization for the Job UI Metrics + +Significantly improved the performance of Job UI Metrics by introducing batch processing that fetches metrics for all jobs in a single API call instead of making individual requests for each job, reducing page load times from minutes to seconds in projects with many jobs and eliminating timeout issues caused by excessive database queries. + + +## Rundeck Open Source Product Updates + +##### ::circle-dot:: [Update Remco to newer commit that remediates some CVEs](https://github.com/rundeck/rundeck/pull/9936) + +Enhanced Docker image security by updating Remco (the configuration management tool) to a newer version that remediates three security vulnerabilities (CVE-2025-4673, CVE-2025-22872, and CVE-2025-47906), strengthening the security posture of Rundeck container deployments. + +##### ::circle-dot:: [Promote workflow tab out of alphaUi](https://github.com/rundeck/rundeck/pull/9928) + +Promote workflow tab out from alpha state. The updated ui will be accessible for all users with the nextUi flag enabled. + +##### ::circle-dot:: [Issues with Ansible inline workflow executions where it shows an unwanted output](https://github.com/rundeck/rundeck/pull/9940) + +Resolved an issue where Ansible inline workflow executions displayed unwanted output by properly sanitizing group names to comply with Ansible requirements, filtering out reserved host attributes that could conflict with Ansible's internal variables, and ensuring only valid host entries are processed during execution. + + +[Here is a link to the full list of public PRs](https://github.com/rundeck/rundeck/pulls?q=is%3Apr+milestone%3A5.19.0+is%3Aclosed) + + +## Links + +- Download the Releases: [Open Source](https://www.rundeck.com/community-downloads/5.19.0) | [Self-Hosted](https://www.rundeck.com/enterprise-downloads/5.19.0) +- [Sign up for Release Notes](https://www.rundeck.com/release-notes-signup) +- [Upgrade instructions](/upgrading/index.md) +- [Catch us on LinkedIn for the Live Stream Release Videos](https://www.linkedin.com/company/pagerduty/events) + +## Version Info + +Name: "Olympus olivedrab music" + +Release Date: February 2nd, 2026 + + +## Community Contributors + +Submit your own Pull Requests to get recognition here! + + + +## Staff Contributors + +* Greg Schueler ([gschueler](https://github.com/gschueler)) +* Carlos Eduardo ([carlosrfranco](https://github.com/carlosrfranco)) +* Eduardo Baltra ([edbaltra](https://github.com/edbaltra)) +* Forrest Evans ([fdevans](https://github.com/fdevans)) +* Jaime Tobar ([jtobard](https://github.com/jtobard)) +* Jake Cohen ([jsboak](https://github.com/jsboak)) +* Jaya Singh ([jayas006](https://github.com/jayas006)) +* Jesus Osuna ([Jesus-Osuna-M](https://github.com/Jesus-Osuna-M)) +* José Vásquez ([hiawvp](https://github.com/hiawvp)) +* Luis Toledo ([ltamaster](https://github.com/ltamaster)) +* Rodrigo Navarro ([ronaveva](https://github.com/ronaveva)) +* Sarah Martinelli Benedetti ([smartinellibenedetti](https://github.com/smartinellibenedetti)) \ No newline at end of file diff --git a/docs/history/release-calendar.md b/docs/history/release-calendar.md index 5a17e69e9..59e26b660 100755 --- a/docs/history/release-calendar.md +++ b/docs/history/release-calendar.md @@ -9,6 +9,7 @@ Upgrade instructions [can be found here](/upgrading/index.md). | Release Version | Release Date | Enterprise Support Status | |------------------------------------------|----------------------|---------------------------| +| [5.19.0](/history/5_x/version-5.19.0.md) | February 2nd, 2025 | Supported | | [5.18.0](/history/5_x/version-5.18.0.md) | December 16th, 2025 | Supported | | [5.17.0](/history/5_x/version-5.17.0.md) | November 3rd, 2025 | Supported | | [5.16.0](/history/5_x/version-5.16.0.md) | October 6th, 2025 | Supported |