New Script: Watcharr (#2243) #1330
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Create Changelog Pull Request | |
on: | |
push: | |
branches: ["main"] | |
workflow_dispatch: | |
jobs: | |
update-changelog-pull-request: | |
runs-on: ubuntu-latest | |
env: | |
CONFIG_PATH: .github/changelog-pr-config.json | |
BRANCH_NAME: github-action-update-changelog | |
AUTOMATED_PR_LABEL: "automated pr" | |
permissions: | |
contents: write | |
pull-requests: write | |
steps: | |
- name: Generate a token | |
id: generate-token | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ vars.APP_ID }} | |
private-key: ${{ secrets.APP_PRIVATE_KEY }} | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Get latest dates in changelog | |
run: | | |
# Extrahiere die neuesten zwei Daten aus dem Changelog | |
DATES=$(grep -E '^## [0-9]{4}-[0-9]{2}-[0-9]{2}' CHANGELOG.md | head -n 2 | awk '{print $2}') | |
LATEST_DATE=$(echo "$DATES" | sed -n '1p') | |
SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p') | |
TODAY=$(date -u +%Y-%m-%d) | |
echo "TODAY=$TODAY" >> $GITHUB_ENV | |
if [[ "$LATEST_DATE" == "$TODAY" ]]; then | |
echo "LATEST_DATE=$SECOND_LATEST_DATE" >> $GITHUB_ENV | |
else | |
echo "LATEST_DATE=$LATEST_DATE" >> $GITHUB_ENV | |
fi | |
- name: Get categorized pull requests | |
id: get-categorized-prs | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const fs = require('fs').promises; | |
const path = require('path'); | |
const configPath = path.resolve(process.env.CONFIG_PATH); | |
const fileContent = await fs.readFile(configPath, 'utf-8'); | |
const changelogConfig = JSON.parse(fileContent); | |
const categorizedPRs = changelogConfig.map(obj => ({ ...obj, notes: [] })); | |
const latestDateInChangelog = new Date(process.env.LATEST_DATE); | |
latestDateInChangelog.setUTCHours(23, 59, 59, 999); | |
const { data: pulls } = await github.rest.pulls.list({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
base: "main", | |
state: "closed", | |
sort: "updated", | |
direction: "desc", | |
per_page: 100, | |
}); | |
pulls.filter(pr => | |
pr.merged_at && | |
new Date(pr.merged_at) > latestDateInChangelog && | |
!pr.labels.some(label => ["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())) | |
).forEach(pr => { | |
const prLabels = pr.labels.map(label => label.name.toLowerCase()); | |
const prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`; | |
for (const { labels, notes } of categorizedPRs) { | |
if (labels.length === 0 || labels.some(label => prLabels.includes(label))) { | |
notes.push(prNote); | |
break; | |
} | |
} | |
}); | |
return categorizedPRs; | |
- name: Update CHANGELOG.md | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const fs = require('fs').promises; | |
const path = require('path'); | |
const today = process.env.TODAY; | |
const latestDateInChangelog = process.env.LATEST_DATE; | |
const changelogPath = path.resolve('CHANGELOG.md'); | |
const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }}; | |
let newReleaseNotes = `## ${today}\n\n### Changes\n\n`; | |
for (const { title, notes } of categorizedPRs) { | |
if (notes.length > 0) { | |
newReleaseNotes += `### ${title}\n\n${notes.join("\n")}\n\n`; | |
} | |
} | |
const changelogContent = await fs.readFile(changelogPath, 'utf-8'); | |
const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`); | |
// Ersetze oder füge Release Notes ein | |
const regex = changelogIncludesTodaysReleaseNotes | |
? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs") | |
: new RegExp(`(?=## ${latestDateInChangelog})`, "gs"); | |
const newChangelogContent = changelogContent.replace(regex, newReleaseNotes); | |
await fs.writeFile(changelogPath, newChangelogContent); | |
- name: Check for changes | |
id: verify-diff | |
run: | | |
git diff --quiet . || echo "changed=true" >> $GITHUB_ENV | |
- name: Commit and push changes | |
if: env.changed == 'true' | |
run: | | |
git config --global user.name "github-actions[bot]" | |
git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
git add CHANGELOG.md | |
git commit -m "Update CHANGELOG.md" | |
git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME | |
git push origin $BRANCH_NAME --force | |
- name: Create pull request if not exists | |
if: env.changed == 'true' | |
env: | |
GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
run: | | |
PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') | |
if [ -z "$PR_EXISTS" ]; then | |
gh pr create --title "[Github Action] Update CHANGELOG.md" \ | |
--body "This PR is auto-generated by a Github Action to update the CHANGELOG.md file." \ | |
--head $BRANCH_NAME \ | |
--base main \ | |
--label "$AUTOMATED_PR_LABEL" | |
fi | |
- name: Approve pull request | |
if: env.changed == 'true' | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') | |
if [ -n "$PR_NUMBER" ]; then | |
gh pr review $PR_NUMBER --approve | |
fi | |
- name: Re-approve pull request after update | |
if: env.changed == 'true' | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number') | |
if [ -n "$PR_NUMBER" ]; then | |
gh pr review $PR_NUMBER --approve | |
fi |