8000
name: contrib | |
on: | |
issue_comment: | |
types: [created] | |
pull_request_target: | |
types: | |
- opened | |
- closed | |
- synchronize | |
- labeled | |
- unlabeled | |
- opened | |
- reopened | |
- edited | |
# For jobs that don't run on draft PRs. | |
- ready_for_review | |
permissions: | |
contents: read | |
# Only run one instance per PR to ensure in-order execution. | |
concurrency: pr-${{ github.ref }} | |
jobs: | |
# Dependabot is annoying, but this makes it a bit less so. | |
auto-approve-dependabot: | |
runs-on: ubuntu-latest | |
if: github.event_name == 'pull_request_target' | |
permissions: | |
pull-requests: write | |
steps: | |
- name: Harden Runner | |
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 | |
with: | |
egress-policy: audit | |
- name: auto-approve dependabot | |
uses: hmarr/auto-approve-action@f0939ea97e9205ef24d872e76833fa908a770363 # v4.0.0 | |
if: github.actor == 'dependabot[bot]' | |
cla: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Harden Runner | |
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 | |
with: | |
egress-policy: audit | |
- name: cla | |
if: (github.event.comment.body == 'r 8000 echeck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' | |
uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# the below token should have repo scope and must be manually added by you in the repository's secret | |
PERSONAL_ACCESS_TOKEN: ${{ secrets.CDRCOMMUNITY_GITHUB_TOKEN }} | |
with: | |
remote-organization-name: "coder" | |
remote-repository-name: "cla" | |
path-to-signatures: "v2022-09-04/signatures.json" | |
path-to-document: "https://github.com/coder/cla/blob/main/README.md" | |
# branch should not be protected | |
branch: "main" | |
# Some users have signed a corporate CLA with Coder so are exempt from signing our community one. | |
allowlist: "coryb,aaronlehmann,dependabot*" | |
release-labels: | |
runs-on: ubuntu-latest | |
# Skip tagging for draft PRs. | |
if: ${{ github.event_name == 'pull_request_target' && !github.event.pull_request.draft }} | |
steps: | |
- name: Harden Runner | |
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 | |
with: | |
egress-policy: audit | |
- name: release-labels | |
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | |
with: | |
# This script ensures PR title and labels are in sync: | |
# | |
# When release/breaking label is: | |
# - Added, rename PR title to include ! (e.g. feat!:) | |
# - Removed, rename PR title to strip ! (e.g. feat:) | |
# | |
# When title is: | |
# - Renamed (+!), add the release/breaking label | |
# - Renamed (-!), remove the release/breaking label | |
script: | | |
const releaseLabels = { | |
breaking: "release/breaking", | |
} | |
const { action, changes, label, pull_request } = context.payload | |
const { title } = pull_request | |
const labels = pull_request.labels.map((label) => label.name) | |
const isBreakingTitle = isBreaking(title) | |
// Debug information. | |
console.log("Action: %s", action) | |
console.log("Title: %s", title) | |
console.log("Labels: %s", labels.join(", ")) | |
const params = { | |
issue_number: context.issue.number, | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
} | |
if (action === "opened" || action === "reopened") { | |
if (isBreakingTitle && !labels.includes(releaseLabels.breaking)) { | |
console.log('Add "%s" label', releaseLabels.breaking) | |
await github.rest.issues.addLabels({ | |
...params, | |
labels: [releaseLabels.breaking], | |
}) | |
} | |
} | |
if (action === "edited" && changes.title) { | |
if (isBreakingTitle && !labels.includes(releaseLabels.breaking)) { | |
console.log('Add "%s" label', releaseLabels.breaking) | |
await github.rest.issues.addLabels({ | |
...params, | |
labels: [releaseLabels.breaking], | |
}) | |
} | |
if (!isBreakingTitle && labels.includes(releaseLabels.breaking)) { | |
const wasBreakingTitle = isBreaking(changes.title.from) | |
if (wasBreakingTitle) { | |
console.log('Remove "%s" label', releaseLabels.breaking) | |
await github.rest.issues.removeLabel({ | |
...params, | |
name: releaseLabels.breaking, | |
}) | |
} else { | |
console.log('Rename title from "%s" to "%s"', title, toBreaking(title)) | |
await github.rest.issues.update({ | |
...params, | |
title: toBreaking(title), | |
}) | |
} | |
} | |
} | |
if (action === "labeled") { | |
if (label.name === releaseLabels.breaking && !isBreakingTitle) { | |
console.log('Rename title from "%s" to "%s"', title, toBreaking(title)) | |
await github.rest.issues.update({ | |
...params, | |
title: toBreaking(title), | |
}) | |
} | |
} | |
if (action === "unlabeled") { | |
if (label.name === releaseLabels.breaking && isBreakingTitle) { | |
console.log('Rename title from "%s" to "%s"', title, fromBreaking(title)) | |
await github.rest.issues.update({ | |
...params, | |
title: fromBreaking(title), | |
}) | |
} | |
} | |
function isBreaking(t) { | |
return t.split(" ")[0].endsWith("!:") | |
} | |
function toBreaking(t) { | |
const parts = t.split(" ") | |
return [parts[0].replace(/:$/, "!:"), ...parts.slice(1)].join(" ") | |
} | |
function fromBreaking(t) { | |
const parts = t.split(" ") | |
return [parts[0].replace(/!:$/, ":"), ...parts.slice(1)].join(" ") | |
} |