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
6 changes: 4 additions & 2 deletions .github/workflows/danger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ jobs:
with:
fetch-depth: 0

- name: Download dangerfile.js
run: wget https://raw.githubusercontent.com/getsentry/github-workflows/${{ inputs._workflow_version }}/danger/dangerfile.js -P ${{ runner.temp }}
- name: Download dangerfile.js and utilities
run: |
wget https://raw.githubusercontent.com/getsentry/github-workflows/${{ inputs._workflow_version }}/danger/dangerfile.js -P ${{ runner.temp }}
wget https://raw.githubusercontent.com/getsentry/github-workflows/${{ inputs._workflow_version }}/danger/dangerfile-utils.js -P ${{ runner.temp }}

# Using a pre-built docker image in GitHub container registry instaed of NPM to reduce possible attack vectors.
- name: Run DangerJS
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/script-tests.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This isn't a reusable workflow but a CI action for this repo itself - testing the contained workflows & scripts.
name: Script Tests
permissions:
contents: read

on:
push:
Expand All @@ -23,3 +25,21 @@ jobs:
- run: Invoke-Pester
working-directory: updater
shell: pwsh

danger:
name: Danger JS Tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: danger
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '18'

- run: node --test

- name: Check syntax
run: node -c dangerfile.js
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Danger - Improve conventional commit scope handling, and non-conventional PR title support ([#105](https://github.com/getsentry/github-workflows/pull/105))
- Add Proguard artifact endpoint for Android builds in sentry-server ([#100](https://github.com/getsentry/github-workflows/pull/100))

### Security
Expand Down
93 changes: 93 additions & 0 deletions danger/dangerfile-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/// Unified configuration for PR flavors (based on real Sentry usage analysis)
const FLAVOR_CONFIG = [
{
labels: ["feat", "feature", "add", "implement"],
changelog: "Features",
isFeature: true
},
{
labels: ["fix", "bug", "bugfix", "resolve", "correct"],
changelog: "Fixes"
},
{
labels: ["sec", "security"],
changelog: "Security"
},
{
labels: ["perf", "performance"],
changelog: "Performance"
},
{
// Internal changes - no changelog needed
changelog: undefined,
labels: [
"docs",
"doc",
"style",
"ref",
"refactor",
"tests",
"test",
"build",
"ci",
"chore",
"meta",
"deps",
"dep",
"update",
"bump",
"cleanup",
"format"
]
}
];

/// Get flavor configuration for a given PR flavor
function getFlavorConfig(prFlavor) {
const normalizedFlavor = prFlavor.toLowerCase().trim();

// Strip scope/context from conventional commit format: "type(scope)" -> "type"
const parenIndex = normalizedFlavor.indexOf('(');
const baseType = parenIndex !== -1 ? normalizedFlavor.substring(0, parenIndex) : normalizedFlavor;

const config = FLAVOR_CONFIG.find(config =>
config.labels.includes(normalizedFlavor) || config.labels.includes(baseType)
);

return config || {
changelog: "Features" // Default to Features
};
}


/// Extract PR flavor from title or branch name
function extractPRFlavor(prTitle, prBranchRef) {
// Validate input parameters to prevent runtime errors
if (prTitle && typeof prTitle === 'string') {
// First try conventional commit format: "type(scope): description"
const colonParts = prTitle.split(":");
if (colonParts.length > 1) {
return colonParts[0].toLowerCase().trim();
}

// Fallback: try first word for non-conventional titles like "fix memory leak"
const firstWord = prTitle.trim().split(/\s+/)[0];
if (firstWord) {
return firstWord.toLowerCase();
}
}

if (prBranchRef && typeof prBranchRef === 'string') {
const parts = prBranchRef.split("/");
if (parts.length > 1) {
return parts[0].toLowerCase();
}
}
return "";
}

module.exports = {
FLAVOR_CONFIG,
getFlavorConfig,
extractPRFlavor
};
Loading
Loading