Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
CV-Gate committed Dec 1, 2024
1 parent 493a841 commit e8058a3
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file added .github/.DS_Store
Binary file not shown.
Binary file added .github/workflows/.DS_Store
Binary file not shown.
48 changes: 48 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Semantic Release Workflow

on:
push:
branches:
- main
- develop
- staging

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "20.8.1"

- name: Clean dependencies
run: rm -rf node_modules package-lock.json

- name: Install dependencies
run: npm install

- name: Debug environment
run: |
echo "JIRA_HOST: $JIRA_HOST"
echo "JIRA_EMAIL: $JIRA_EMAIL"
echo "JIRA_API_TOKEN: [hidden]"
echo "JIRA_PROJECT_KEY: $JIRA_PROJECT_KEY"
env:
JIRA_HOST: ${{ secrets.JIRA_HOST }}
JIRA_EMAIL: ${{ secrets.JIRA_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
JIRA_PROJECT_KEY: ${{ secrets.JIRA_PROJECT_KEY }}

- name: Run Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JIRA_HOST: ${{ secrets.JIRA_HOST }}
JIRA_EMAIL: ${{ secrets.JIRA_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
JIRA_PROJECT_KEY: ${{ secrets.JIRA_PROJECT_KEY }}
run: npx semantic-release
96 changes: 96 additions & 0 deletions jira-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const axios = require("axios");

module.exports = {
verifyConditions: async (pluginConfig, { logger }) => {
logger.log("Verifying Jira conditions...");
if (!process.env.JIRA_HOST || !process.env.JIRA_EMAIL || !process.env.JIRA_API_TOKEN) {
throw new Error("Jira credentials are missing (JIRA_HOST, JIRA_EMAIL, JIRA_API_TOKEN).");
}
},

success: async (pluginConfig, context) => {
const { nextRelease, lastRelease, commits, branch, logger } = context;
const jiraHost = process.env.JIRA_HOST;
const jiraEmail = process.env.JIRA_EMAIL;
const jiraApiToken = process.env.JIRA_API_TOKEN;
const projectId = process.env.JIRA_PROJECT_KEY; // Example: SSP

// Only process RC or stable branches
if (!["main", "staging"].includes(branch.name)) {
logger.log(`Skipping Fix Version update for branch ${branch.name}.`);
return;
}

const releaseType = branch.name === "main" ? "stable" : "rc";

logger.log(`Processing commits since the last release: ${lastRelease.gitTag || "none"}`);

// Extract Jira ticket IDs from new commits
const ticketRegex = /\b([A-Z]+-\d+)\b/g;
const ticketIds = Array.from(
new Set(
commits
.filter((commit) => commit.message) // Ensure the commit has a message
.map((commit) => commit.message.match(ticketRegex)) // Extract ticket IDs
.flat()
.filter(Boolean) // Remove null or undefined matches
)
);

if (ticketIds.length === 0) {
logger.log("No Jira tickets found in new commits.");
return;
}

logger.log(`Found Jira tickets: ${ticketIds.join(", ")}`);

// Create or update the Fix Version in Jira
const fixVersion = {
name: nextRelease.version,
description: `Release ${nextRelease.version} (${releaseType})`,
released: releaseType === "stable", // Mark as released for stable releases
releaseDate: new Date().toISOString().split("T")[0], // Format: YYYY-MM-DD
};

try {
// Check if Fix Version exists
const { data: existingVersions } = await axios.get(
`${jiraHost}/rest/api/2/project/${projectId}/versions`,
{ auth: { username: jiraEmail, password: jiraApiToken } }
);

const existingVersion = existingVersions.find((v) => v.name === fixVersion.name);
let versionId;

if (existingVersion) {
versionId = existingVersion.id;
logger.log(`Fix Version "${fixVersion.name}" already exists.`);
} else {
// Create Fix Version
const { data: newVersion } = await axios.post(
`${jiraHost}/rest/api/2/version`,
{ ...fixVersion, project: projectId },
{ auth: { username: jiraEmail, password: jiraApiToken } }
);
versionId = newVersion.id;
logger.log(`Created Fix Version "${fixVersion.name}".`);
}

// Update tickets with the Fix Version
await Promise.all(
ticketIds.map((ticketId) =>
axios.put(
`${jiraHost}/rest/api/2/issue/${ticketId}`,
{ fields: { fixVersions: [{ id: versionId }] } },
{ auth: { username: jiraEmail, password: jiraApiToken } }
)
)
);

logger.log(`Updated Fix Version for tickets: ${ticketIds.join(", ")}`);
} catch (error) {
logger.error("Failed to update Jira Fix Versions:", error.message);
throw error;
}
},
};
14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"devDependencies": {
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^11.0.1",
"conventional-changelog-conventionalcommits": "^8.0.0",
"execa": "^9.5.1",
"semantic-release": "^24.2.0",
"semantic-release-jira-releases": "^0.7.2"
},
"dependencies": {
"axios": "^1.7.8"
}
}
46 changes: 46 additions & 0 deletions release.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module.exports = {
branches: [
{ name: "main" }, // Stable production releases
{ name: "develop", prerelease: "beta" }, // Beta pre-releases for ongoing development
{ name: "staging", prerelease: "rc" }, // RC (release candidate) pre-releases
],
plugins: [

[
"@semantic-release/commit-analyzer",
{
preset: "conventionalcommits",
releaseRules: [
{ type: "feat", release: "minor" }, // Features trigger minor release
{ type: "fix", release: "patch" }, // Fixes trigger patch release
{ breaking: true, release: "major" }, // Breaking changes trigger major release
{ type: "docs", release: false }, // Documentation changes are ignored
{ type: "chore", release: false }, // Chores are ignored
],
parserOpts: {
noteKeywords: ["BREAKING CHANGE", "BREAKING CHANGES"],
},
},
],

"@semantic-release/release-notes-generator",

[
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md",
},
],

[
"@semantic-release/git",
{
assets: ["CHANGELOG.md"],
message: "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
},
],

"@semantic-release/github",
"./jira-plugin",
],
};

0 comments on commit e8058a3

Please sign in to comment.