mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-04 02:04:06 +00:00
fix(changelog): correct fragments for the UI (#11952)
This commit is contained in:
@@ -14,19 +14,19 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
sdk_version:
|
||||
description: 'SDK version override (empty = auto-derive from prowler/CHANGELOG.md + pending fragment types; "skip" = hold this component back)'
|
||||
description: 'SDK version override (empty = mirrors prowler_version; "skip" = hold this component back)'
|
||||
required: false
|
||||
type: string
|
||||
api_version:
|
||||
description: 'API version override (empty = auto-derive; "skip" = hold back)'
|
||||
description: 'API version override (empty = auto-derive 1.<prowler_minor + 1>.<prowler_patch>; "skip" = hold back)'
|
||||
required: false
|
||||
type: string
|
||||
ui_version:
|
||||
description: 'UI version override (empty = auto-derive; "skip" = hold back)'
|
||||
description: 'UI version override (empty = auto-derive 1.<prowler_minor>.<prowler_patch>; "skip" = hold back)'
|
||||
required: false
|
||||
type: string
|
||||
mcp_version:
|
||||
description: 'MCP Server version override (empty = auto-derive; "skip" = hold back)'
|
||||
description: 'MCP Server version override (empty = auto-derive from pending fragment types; "skip" = hold back)'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
@@ -209,17 +209,48 @@ jobs:
|
||||
errors=1
|
||||
continue
|
||||
fi
|
||||
IFS=. read -r major minor patch <<< "$current"
|
||||
major=$((10#$major))
|
||||
minor=$((10#$minor))
|
||||
patch=$((10#$patch))
|
||||
if echo "$fragments" | grep -qE '\.(added|changed|deprecated)(\.[0-9]+)?\.md$'; then
|
||||
effective="${major}.$((minor + 1)).0"
|
||||
else
|
||||
effective="${major}.${minor}.$((patch + 1))"
|
||||
# SDK, UI, and API versions are deterministic mirrors of the
|
||||
# Prowler version (the scheme bump-version.yml codifies): the SDK
|
||||
# mirrors it directly, the UI tracks 1.<minor>.<patch>, and the
|
||||
# API is the independent 1.<minor + 1>.<patch> stream. Only the
|
||||
# MCP Server has its own cadence, derived from fragment types.
|
||||
IFS=. read -r _ prowler_minor prowler_patch <<< "$PROWLER_VERSION"
|
||||
prowler_minor=$((10#$prowler_minor))
|
||||
prowler_patch=$((10#$prowler_patch))
|
||||
case "$component" in
|
||||
prowler) effective="$PROWLER_VERSION" ;;
|
||||
ui) effective="1.${prowler_minor}.${prowler_patch}" ;;
|
||||
api) effective="1.$((prowler_minor + 1)).${prowler_patch}" ;;
|
||||
mcp_server)
|
||||
IFS=. read -r major minor patch <<< "$current"
|
||||
major=$((10#$major))
|
||||
minor=$((10#$minor))
|
||||
patch=$((10#$patch))
|
||||
# Prowler patch releases (vN.N target) are maintenance
|
||||
# releases, so the MCP Server bumps patch regardless of
|
||||
# fragment types; a deliberate exception needs the explicit
|
||||
# version input.
|
||||
if [ "$TARGET_BRANCH" != "master" ]; then
|
||||
effective="${major}.${minor}.$((patch + 1))"
|
||||
if echo "$fragments" | grep -qE '\.(added|deprecated)(\.[0-9]+)?\.md$'; then
|
||||
echo "::warning::${component}: 'added'/'deprecated' fragments are shipping in a Prowler patch; auto-derived a patch bump (${current} -> ${effective}), pass the version input to override"
|
||||
fi
|
||||
elif echo "$fragments" | grep -qE '\.(added|changed|deprecated)(\.[0-9]+)?\.md$'; then
|
||||
effective="${major}.$((minor + 1)).0"
|
||||
else
|
||||
effective="${major}.${minor}.$((patch + 1))"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
current_key=$(version_key "$current")
|
||||
effective_key=$(version_key "$effective")
|
||||
if [[ "$effective_key" < "$current_key" || "$effective_key" == "$current_key" ]]; then
|
||||
echo "::error::${component}: auto-derived version '${effective}' is not greater than the latest released version (${current}); check prowler_version or pass the version input explicitly"
|
||||
errors=1
|
||||
continue
|
||||
fi
|
||||
mode="auto"
|
||||
echo "::notice::${component}: version auto-derived ${current} -> ${effective} from the pending fragment types"
|
||||
echo "::notice::${component}: version auto-derived ${current} -> ${effective}"
|
||||
fi
|
||||
|
||||
if [ "$removed_fragments" = "true" ]; then
|
||||
@@ -336,6 +367,7 @@ jobs:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
labels: |
|
||||
no-changelog
|
||||
skip-sync
|
||||
|
||||
# Patch compiles (target_branch = v5.X) leave master holding the consumed
|
||||
# fragments and missing the new version block. This applies the equivalent
|
||||
@@ -366,7 +398,7 @@ jobs:
|
||||
local block_file="$2"
|
||||
local changelog="${component}/CHANGELOG.md"
|
||||
local incoming_heading incoming_release incoming_key
|
||||
local marker_line insertion_line duplicate_line
|
||||
local marker_line insertion_line duplicate_line total_lines
|
||||
local line heading existing_release existing_key
|
||||
|
||||
marker_line=$(grep -n -m1 '^<!-- changelog: release notes start -->$' "$changelog" | cut -d: -f1)
|
||||
@@ -405,9 +437,25 @@ jobs:
|
||||
insertion_line=$((marker_line + 1))
|
||||
fi
|
||||
|
||||
# The captured block window can be off by one blank line on either
|
||||
# end (towncrier re-emits the blank after the marker), so strip the
|
||||
# outer blank lines and pad exactly one on each side: the block
|
||||
# must never glue to the marker above or the next heading below.
|
||||
awk '
|
||||
/[^[:space:]]/ { for (i = 0; i < pending; i++) print ""; pending = 0; print; started = 1; next }
|
||||
started { pending++ }
|
||||
' "$block_file" > "${RUNNER_TEMP}/block-normalized.md"
|
||||
|
||||
total_lines=$(wc -l < "$changelog")
|
||||
{
|
||||
head -n "$((insertion_line - 1))" "$changelog"
|
||||
cat "$block_file"
|
||||
if [ "$insertion_line" -gt 1 ] && [ -n "$(sed -n "$((insertion_line - 1))p" "$changelog")" ]; then
|
||||
echo ""
|
||||
fi
|
||||
cat "${RUNNER_TEMP}/block-normalized.md"
|
||||
if [ "$insertion_line" -le "$total_lines" ]; then
|
||||
echo ""
|
||||
fi
|
||||
tail -n +"$insertion_line" "$changelog"
|
||||
} > "${RUNNER_TEMP}/changelog.tmp"
|
||||
mv "${RUNNER_TEMP}/changelog.tmp" "$changelog"
|
||||
@@ -476,3 +524,4 @@ jobs:
|
||||
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
|
||||
labels: |
|
||||
no-changelog
|
||||
skip-sync
|
||||
|
||||
+1
-1
@@ -4,7 +4,6 @@ All notable changes to the **Prowler API** are documented in this file.
|
||||
|
||||
<!-- changelog: release notes start -->
|
||||
|
||||
|
||||
## [1.34.1] (Prowler v5.33.1)
|
||||
|
||||
### 🐞 Fixed
|
||||
@@ -19,6 +18,7 @@ All notable changes to the **Prowler API** are documented in this file.
|
||||
- `LIGHTHOUSE_AI_OPENAI_COMPATIBLE_ALLOWED_HOSTS` environment variable to allow internal hosts as OpenAI-compatible Lighthouse AI base URLs [(#11942)](https://github.com/prowler-cloud/prowler/pull/11942)
|
||||
|
||||
---
|
||||
|
||||
## [1.34.0] (Prowler v5.33.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
@@ -4,7 +4,6 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
<!-- changelog: release notes start -->
|
||||
|
||||
|
||||
## [5.33.1] (Prowler v5.33.1)
|
||||
|
||||
### 🐞 Fixed
|
||||
@@ -17,6 +16,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
- Azure Function App optional permission failures now log as warnings, and Function App environment variable fields use the correct spelling internally [(#11926)](https://github.com/prowler-cloud/prowler/pull/11926)
|
||||
|
||||
---
|
||||
|
||||
## [5.33.0] (Prowler v5.33.0)
|
||||
|
||||
### 🐞 Fixed
|
||||
|
||||
@@ -153,9 +153,9 @@ The `pr-check-changelog.yml` workflow enforces fragments:
|
||||
|
||||
## Release flow (compile)
|
||||
|
||||
- At release time, the `compile-changelogs` workflow (manual dispatch: `prowler_version` + `target_branch`; per-component versions are auto-derived from each changelog's latest stamped heading plus the pending fragment types, with optional explicit overrides or `skip`) resolves each fragment's PR from git history, runs the compiler per component, and opens a `chore(changelog): vX.Y.Z` PR (labeled `no-changelog`) that inserts the stamped `## [X.Y.Z] (Prowler vX.Y.Z)` block into each `CHANGELOG.md` and deletes the consumed fragments. A human reviews and squash-merges it. `prepare-release.yml` then extracts the stamped sections exactly as before.
|
||||
- At release time, the `compile-changelogs` workflow (manual dispatch: `prowler_version` + `target_branch`; per-component versions are auto-derived by mirroring the Prowler version — SDK mirrors it directly, UI is `1.<minor>.<patch>`, API is `1.<minor + 1>.<patch>`, and only the MCP Server derives from its pending fragment types — with optional explicit overrides or `skip`) resolves each fragment's PR from git history, runs the compiler per component, and opens a `chore(changelog): vX.Y.Z` PR (labeled `no-changelog` and `skip-sync`) that inserts the stamped `## [X.Y.Z] (Prowler vX.Y.Z)` block into each `CHANGELOG.md` and deletes the consumed fragments. A human reviews and squash-merges it. `prepare-release.yml` then extracts the stamped sections exactly as before.
|
||||
- **Minor release (X.Y.0):** compile on `master` and merge the compile PR BEFORE cutting the `v5.X` branch.
|
||||
- **Patch release (X.Y.Z):** fixes are backported to `v5.X` with their fragment files (conflict-free); compile on `v5.X` and merge its PR there. The same workflow run automatically opens a second forward-sync PR against master (labeled `no-changelog`) that inserts the same stamped block under master's marker and deletes the consumed fragments, so the next minor cannot re-release them; merge it right after. Fragments that only existed on `v5.X` are skipped with a notice. No manual git is involved.
|
||||
- **Patch release (X.Y.Z):** fixes are backported to `v5.X` with their fragment files (conflict-free); compile on `v5.X` and merge its PR there. The same workflow run automatically opens a second forward-sync PR against master (labeled `no-changelog` and `skip-sync`) that inserts the same stamped block under master's marker and deletes the consumed fragments, so the next minor cannot re-release them; merge it right after. Fragments that only existed on `v5.X` are skipped with a notice. No manual git is involved.
|
||||
- Entries within a section are ordered by PR number ascending (approximately chronological). Do not fight this ordering.
|
||||
|
||||
## Fixing an already-released entry
|
||||
|
||||
@@ -312,3 +312,68 @@ def test_compile_workflow_requires_removed_fragments_in_major_releases():
|
||||
assert "effective_major" in workflow
|
||||
assert "effective_minor" in workflow
|
||||
assert "effective_patch" in workflow
|
||||
|
||||
|
||||
def test_compile_workflow_prs_skip_cloud_sync():
|
||||
workflow = read_workflow("compile-changelogs.yml")
|
||||
labels_blocks = re.findall(r"labels: \|\n((?:\s+[a-z-]+\n)+)", workflow)
|
||||
|
||||
assert len(labels_blocks) == 2
|
||||
for block in labels_blocks:
|
||||
assert "no-changelog" in block.split()
|
||||
assert "skip-sync" in block.split()
|
||||
|
||||
|
||||
def test_compile_workflow_auto_derives_versions_by_mirroring_prowler_version():
|
||||
workflow = read_workflow("compile-changelogs.yml")
|
||||
|
||||
assert 'prowler) effective="$PROWLER_VERSION" ;;' in workflow
|
||||
assert 'ui) effective="1.${prowler_minor}.${prowler_patch}" ;;' in workflow
|
||||
assert 'api) effective="1.$((prowler_minor + 1)).${prowler_patch}" ;;' in workflow
|
||||
assert (
|
||||
"auto-derived version '${effective}' is not greater than the latest released version"
|
||||
in workflow
|
||||
)
|
||||
|
||||
|
||||
def test_compile_workflow_auto_derives_mcp_patch_bumps_on_patch_releases():
|
||||
workflow = read_workflow("compile-changelogs.yml")
|
||||
|
||||
assert "'added'/'deprecated' fragments are shipping in a Prowler patch" in workflow
|
||||
assert (
|
||||
"elif echo \"$fragments\" | grep -qE '\\.(added|changed|deprecated)(\\.[0-9]+)?\\.md$'; then"
|
||||
in workflow
|
||||
)
|
||||
|
||||
|
||||
def test_forward_sync_pads_release_blocks_with_blank_lines():
|
||||
workflow = read_workflow("compile-changelogs.yml")
|
||||
|
||||
assert "block-normalized.md" in workflow
|
||||
assert 'total_lines=$(wc -l < "$changelog")' in workflow
|
||||
assert '[ -n "$(sed -n "$((insertion_line - 1))p" "$changelog")" ]' in workflow
|
||||
assert 'if [ "$insertion_line" -le "$total_lines" ]; then' in workflow
|
||||
|
||||
|
||||
def test_component_changelogs_separate_release_blocks_with_blank_lines():
|
||||
for component in COMPONENTS:
|
||||
lines = (REPO_ROOT / component / "CHANGELOG.md").read_text().splitlines()
|
||||
marker_line = lines.index("<!-- changelog: release notes start -->")
|
||||
|
||||
assert (
|
||||
lines[marker_line + 1] == ""
|
||||
), f"{component}/CHANGELOG.md: expected a blank line after the marker"
|
||||
assert (
|
||||
lines[marker_line + 2] != ""
|
||||
), f"{component}/CHANGELOG.md: expected a single blank line after the marker"
|
||||
for index, line in enumerate(lines):
|
||||
if line == "---" and index + 1 < len(lines):
|
||||
assert lines[index + 1] == "", (
|
||||
f"{component}/CHANGELOG.md line {index + 2}: "
|
||||
"expected a blank line after '---'"
|
||||
)
|
||||
if line.startswith("## ["):
|
||||
assert lines[index - 1] == "", (
|
||||
f"{component}/CHANGELOG.md line {index}: "
|
||||
"expected a blank line before a release heading"
|
||||
)
|
||||
|
||||
+2
-2
@@ -4,8 +4,7 @@ All notable changes to the **Prowler UI** are documented in this file.
|
||||
|
||||
<!-- changelog: release notes start -->
|
||||
|
||||
|
||||
## [1.34.0] (Prowler v5.33.1)
|
||||
## [1.33.1] (Prowler v5.33.1)
|
||||
|
||||
### 🔄 Changed
|
||||
|
||||
@@ -17,6 +16,7 @@ All notable changes to the **Prowler UI** are documented in this file.
|
||||
- Jira dispatch polling now reports failed issue creation tasks instead of treating partial failures as successful [(#11925)](https://github.com/prowler-cloud/prowler/pull/11925)
|
||||
|
||||
---
|
||||
|
||||
## [1.33.0] (Prowler v5.33.0)
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
Reference in New Issue
Block a user