Skip to content
Merged
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
104 changes: 104 additions & 0 deletions .github/workflows/release-to-branches-with-label.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: On Pull Request Merged to Master

on:
pull_request:
# Only trigger on pull requests targeting main/master
branches:
- master
- main
types:
- closed

jobs:
run-on-pr-merged:
runs-on: ubuntu-latest

# Only run if the PR was actually merged
if: ${{ github.event.pull_request.merged == true }}

steps:
- name: Add a comment to the merged PR (only if labeler is in the org)
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ORG_GH_TOKEN }}
script: |
// 1. The label format: e.g., "release-1", "release-1.0"
const labelRegex = /^release-[0-9]+(\.[0-9]+)?$/;

// 2. Get PR info
const pullRequestNumber = context.payload.pull_request.number;
const labelsOnPR = context.payload.pull_request.labels || [];
console.log("Labels on the Pull Request:", labelsOnPR.map(label => label.name));
// 3. Get all timeline events to see who labeled the PR
const { data: prEvents } = await github.rest.issues.listEvents({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pullRequestNumber
});

// 4. Filter down to "labeled" events
const labeledEvents = prEvents.filter(ev => ev.event === 'labeled');
console.log("Labeled Events:",labeledEvents.map(event => ({
label: event.label?.name,
user: event.actor?.login,
timestamp: event.created_at
})));
// 5. Build a map: labelName -> last user who added it
// (We reverse to get the *most recent* labeler, if a label was added multiple times)
const labelToLastLabeler = {};
for (const event of labeledEvents.reverse()) {
const labelName = event.label?.name;
const userName = event.actor?.login;
if (labelName && userName && !labelToLastLabeler[labelName]) {
labelToLastLabeler[labelName] = userName;
}
}

// 6. For each label on the PR, check if it matches "release-.."
// If yes, we see who labeled it last and check their membership
for (const label of labelsOnPR) {
if (labelRegex.test(label.name)) {
const userWhoAddedLabel = labelToLastLabeler[label.name];

// If there's no recorded user (edge case), skip
if (!userWhoAddedLabel) {
console.log(`User not found for label: ${label.name}`);
continue;
}

// 7. Check if the user is in the org
let isMember = false;
try {
await github.rest.orgs.checkMembershipForUser({
org: 'TykTechnologies',
username: userWhoAddedLabel
});
// If this call succeeds, they're a member
isMember = true;
console.log(`User '${userWhoAddedLabel}' is a member of the organization '${'TykTechnologies'}'.`);
} catch (error) {
// If 404, user is not a member. Anything else is an unexpected error.
if (error.status === 404) {
console.log(`User '${userWhoAddedLabel}' is NOT a member of the organization '${'TykTechnologies'}'.`);
}else {
console.error(`An error occurred while checking membership for user '${userWhoAddedLabel}':`, error);
throw error;
}
}

// 8. Comment only if user is in the org
if (isMember) {
console.log(`Creating comment for label '${label.name}' on PR #${pullRequestNumber} by user '${userWhoAddedLabel}'.`);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pullRequestNumber,
body: `/release to ${label.name}`
});
}else{
console.log(`No comment created for label '${label.name}' on PR #${pullRequestNumber} because the user '${userWhoAddedLabel}' is not a member of the organization 'TykTechnologies'.`);
}
}else{
console.log(`Label '${label.name}' does not match the expected format.`);
}
}
Loading