Skip to content
60 changes: 45 additions & 15 deletions .github/scripts/release-index/build-releases.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const { load } = require("js-yaml");

const OWNER = "codefresh-io";
const REPO = "gitops-runtime-helm";
const LATEST_PATTERN = /^(\d{4})\.(\d{1,2})-(\d+)$/;
const LATEST_PATTERN = /^(\d{2})\.(\d{1,2})-(\d+)$/; // Format: YY.MM-patch (e.g., 25.04-1)
const MIN_STABLE_VERSION = "1.0.0";
const TOKEN = process.env.GITHUB_TOKEN;
const SECURITY_FIXES_STRING =
process.env.SECURITY_FIXES_STRING || "### Security Fixes:";
Expand All @@ -22,6 +23,11 @@ if (!TOKEN) {

const octokit = new Octokit({ auth: TOKEN });

/**
* Detect channel based on version format
* - Latest: YY.MM-patch format (e.g., 25.04-1)
* - Stable: Semver format starting from 1.0.0 (e.g., 1.2.3)
*/
function detectChannel(version) {
const match = version.match(LATEST_PATTERN);
if (match) {
Expand All @@ -30,12 +36,26 @@ function detectChannel(version) {
return "latest";
}
}

return "stable";
}

function isValidChannelVersion(normalized, channel) {
if (!semver.valid(normalized)) {
return false;
}

if (channel === "stable") {
return semver.gte(normalized, MIN_STABLE_VERSION);
}

return true;
}

/**
* Normalize version for semver validation
* Converts: 2025.01-1 → 2025.1.1
* - Latest channel: 25.01-1 → 25.1.1
* - Stable channel: 1.2.3 → 1.2.3 (no change)
*/
function normalizeVersion(version, channel) {
if (channel === "latest") {
Expand All @@ -50,10 +70,6 @@ function normalizeVersion(version, channel) {
return version;
}

function isValidVersion(normalized) {
return !!semver.valid(normalized);
}

function compareVersions(normA, normB) {
try {
return semver.compare(normA, normB);
Expand Down Expand Up @@ -145,11 +161,14 @@ function processReleases(rawReleases) {
}

const channel = detectChannel(version);

const normalized = normalizeVersion(version, channel);

if (!isValidVersion(normalized)) {
console.log(` ⚠️ Skipping invalid version: ${version}`);
if (!isValidChannelVersion(normalized, channel)) {
const reason =
channel === "stable"
? `not valid semver >= ${MIN_STABLE_VERSION}`
: "not valid semver";
console.log(` ⚠️ Skipping invalid ${channel} version: ${version} (${reason})`);
skipped++;
continue;
}
Expand Down Expand Up @@ -196,7 +215,8 @@ async function buildChannelData(channelReleases, channelName) {
release.appVersion = await getAppVersionFromChart(release.version);
}

const latestVersion = sorted[0]?.version;
const latestRelease = sorted[0] || null;
const latestVersion = latestRelease?.version;
const latestSecureIndex = latestWithSecurityFixes
? sorted.findIndex((r) => r.version === latestWithSecurityFixes)
: -1;
Expand All @@ -209,8 +229,8 @@ async function buildChannelData(channelReleases, channelName) {

return {
releases: topReleases,
latestChartVersion: sorted[0]?.version || null,
latestWithSecurityFixes,
latestRelease,
};
}

Expand Down Expand Up @@ -242,12 +262,12 @@ async function buildIndex() {
channels: {
stable: {
releases: stable.releases,
latestChartVersion: stable.latestChartVersion,
latestRelease: stable.latestRelease,
latestWithSecurityFixes: stable.latestWithSecurityFixes,
},
latest: {
releases: latest.releases,
latestChartVersion: latest.latestChartVersion,
latestRelease: latest.latestRelease,
latestWithSecurityFixes: latest.latestWithSecurityFixes,
},
},
Expand All @@ -272,7 +292,12 @@ async function buildIndex() {
console.log(` Total releases: ${index.stats.totalReleases}`);
console.log(`\n 🟢 Stable Channel:`);
console.log(
` Latest: ${index.channels.stable.latestChartVersion || "none"}`
` Latest chart: ${index.channels.stable.latestRelease?.version || "none"}`
);
console.log(
` Latest app: ${
index.channels.stable.latestRelease?.appVersion || "none"
}`
);
console.log(
` Latest secure: ${
Expand All @@ -281,7 +306,12 @@ async function buildIndex() {
);
console.log(`\n 🔵 Latest Channel:`);
console.log(
` Latest: ${index.channels.latest.latestChartVersion || "none"}`
` Latest chart: ${index.channels.latest.latestRelease?.version || "none"}`
);
console.log(
` Latest app: ${
index.channels.latest.latestRelease?.appVersion || "none"
}`
);
console.log(
` Latest secure: ${
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-index.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Update Release Index
name: update-release-index

on:
release:
Expand Down