Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1ad707e
commit f6c1b37
Showing
7 changed files
with
378 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
name: Milestone Changelog | ||
description: Re-generates changelog for given milestone | ||
inputs: | ||
milestone: | ||
description: Milestone object containing number and title | ||
required: true | ||
token: | ||
description: Github token | ||
required: true | ||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Parse input | ||
id: args | ||
shell: bash | ||
run: | | ||
echo "::set-output name=milestone_title::${{ fromJSON(inputs.milestone).title }}" | ||
echo "::set-output name=milestone_number::${{ fromJSON(inputs.milestone).number }}" | ||
# The gh utility has a shortcut to filter merged PRs by milestone, while it would require | ||
# multiple calls in JS rest client | ||
- name: Find Merged Pull Requsts | ||
id: merged_milestone | ||
shell: bash | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.token }} | ||
run: | | ||
prs="$(gh pr list \ | ||
--repo '${{ github.repository }}' \ | ||
--search 'milestone:${{ steps.args.outputs.milestone_title }}' \ | ||
--state merged \ | ||
--json number,url,title,body,state,milestone)" | ||
echo "::set-output name=prs::${prs}" | ||
- name: Collect Changelog | ||
id: changelog | ||
uses: deckhouse/changelog-action@main | ||
with: | ||
token: ${{ inputs.token }} | ||
pull_requests: ${{ steps.merged_milestone.outputs.prs }} | ||
|
||
- name: Write Changelog File | ||
id: file | ||
shell: bash | ||
run: | | ||
mkdir -p ./CHANGELOG | ||
filename='./CHANGELOG/CHANGELOG-${{ steps.args.outputs.milestone_title }}.yml' | ||
cat > "$filename" <<EOBODYINACTION | ||
${{ steps.changelog.outputs.yaml }} | ||
EOBODYINACTION | ||
- name: Create Pull Request | ||
uses: peter-evans/create-pull-request@v3.10.1 | ||
with: | ||
commit-message: Re-generate changelog | ||
base: main | ||
branch: changelog/${{ steps.args.outputs.milestone_title }} | ||
milestone: ${{ steps.args.outputs.milestone_number }} | ||
title: Changelog ${{ steps.args.outputs.milestone_title }} | ||
body: ${{ steps.changelog.outputs.markdown }} | ||
labels: changelog, auto | ||
token: ${{ inputs.token }} | ||
delete-branch: true |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
## Description | ||
<!--- | ||
Describe your changes in detail. | ||
Please let users know if your feature influences critical cluster components | ||
(restarts of ingress-controllers, control-plane, Prometheus, etc). | ||
--> | ||
|
||
## Why we need it and what problem does it solve? | ||
<!--- | ||
This is the most important paragraph. | ||
You have to describe the main goal of your feature. | ||
If it fixes an issue, place a link to the issue here. | ||
If it fixes an obvious bug, please tell users about the impact and effect of the problem. | ||
--> | ||
|
||
## Changelog entries | ||
<!--- | ||
Describe the changes so they will be included in a release changelog. | ||
Find examples and documentation below. | ||
--> | ||
|
||
```changes | ||
module: <kebab-case> | ||
type: fix | feature | ||
description: <what effectively changes> | ||
note: <what to expect> | ||
``` | ||
|
||
<!--- | ||
ABOUT CHANGES BLOCK | ||
"Changes" block contains a list of YAML documents. It describes a changelog | ||
entry that is collected to a release changelog. | ||
Fields: | ||
module | ||
Required. Affected module in kebab case, e.g. "node-manager". | ||
type | ||
Required. The change type: only "fix" and "feature" supported. | ||
description | ||
Optional. The changelog entry. Omit to use pull request title. | ||
note | ||
Optional. Any notable detail, e.g. expected restarts, downtime, config changes, migrations, etc. | ||
Since the syntax is YAML, `note` may contain multi-line text. | ||
There can be multiple docs in single `changes` block, and multiple `changes` | ||
blocks in the PR body. | ||
Example: | ||
```changes | ||
module: node-manager | ||
type: fix | ||
description: "Nodes with outdated manifests are no longer provisioned on *InstanceClass update." | ||
note: | | ||
Expect nodes of "Cloud" type to restart. | ||
Node checksum calculation is fixes as well as a race condition during | ||
the machines (MCM) rendering which caused outdated nodes to spawn. | ||
--- | ||
module: cloud-provider-aws | ||
type: feature | ||
description: "Node restarts can be avoided by pinning a checksum to a node group in config values." | ||
note: Recommended to use as a last resort. | ||
``` | ||
--> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
//@ts-check | ||
|
||
// Gets issue in context, ensures it is PR with milestone, and returns the milestone | ||
module.exports = async ({ github, core, context }) => { | ||
const { status, data: issue } = await github.rest.issues.get({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.issue.number, | ||
}); | ||
|
||
if (status != 200) { | ||
core.warning(`GET issue error: status ${status}`); | ||
return; | ||
} | ||
|
||
const whatsWrong = validate(issue); | ||
if (whatsWrong) { | ||
core.warning(whatsWrong); | ||
return; | ||
} | ||
|
||
return issue.milestone && issue.milestone.status == "open"; | ||
}; | ||
|
||
function validate(issue) { | ||
if (!issue.pull_request) { | ||
return "Not pull request, skip."; | ||
} | ||
|
||
if (!issue.milestone) { | ||
return "No milestone, skip."; | ||
} | ||
|
||
if (issue.milestone.state != "open") { | ||
return `Milestone ${issue.milestone.title} is not open.`; | ||
} | ||
|
||
return ""; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: Changelog Command Dispatch | ||
on: | ||
issue_comment: | ||
types: [created] | ||
jobs: | ||
dispatch: | ||
name: Dispatch Changelog Event | ||
runs-on: ubuntu-latest | ||
if: | | ||
github.event.issue.pull_request && | ||
github.event.issue.milestone.state == 'open' && | ||
contains(github.event.issue.labels.*.name, 'changelog') && | ||
contains(github.event.issue.labels.*.name, 'auto') | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
|
||
- name: Find milestone | ||
id: milestone | ||
uses: actions/github-script@v5 | ||
with: | ||
result-encoding: json | ||
script: | | ||
const validate = require('./.github/scripts/changelog-command-validate.js') | ||
return await validate({ github, core, context }) | ||
- name: Slash Command Dispatch | ||
if: steps.milestone.outputs.result | ||
uses: peter-evans/slash-command-dispatch@v2 | ||
with: | ||
token: ${{ secrets.CHANGELOG_ACCESS_TOKEN }} | ||
commands: changelog | ||
dispatch-type: repository | ||
issue-type: pull-request |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Changelog Command | ||
on: | ||
repository_dispatch: | ||
types: [changelog-command] | ||
jobs: | ||
changelog: | ||
name: Milestone Changelog | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
|
||
- name: Upgrade changelog | ||
uses: ./.github/actions/milestone-changelog | ||
with: | ||
milestone: ${{ toJSON( github.event.client_payload.pull_request.milestone ) }} | ||
token: ${{ secrets.CHANGELOG_ACCESS_TOKEN }} | ||
|
||
- name: Add reaction for success | ||
uses: peter-evans/create-or-update-comment@v1 | ||
with: | ||
token: ${{ secrets.CHANGELOG_ACCESS_TOKEN }} | ||
repository: ${{ github.event.client_payload.github.payload.repository.full_name }} | ||
comment-id: ${{ github.event.client_payload.github.payload.comment.id }} | ||
reaction-type: hooray |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Changelog Workflows | ||
|
||
## What they do | ||
|
||
Release changelog is generated on milestone assignment or PR merging or by calling command | ||
`/changelog` in 'changelog PR' comments. | ||
|
||
### Requirements | ||
|
||
Changelog generation relies on repo secret `CHANGELOG_ACCESS_TOKEN` which must | ||
have `workflow` permission. | ||
|
||
### Code | ||
|
||
The changelog toolchain consists of these files | ||
|
||
``` | ||
.github/ | ||
actions/ | ||
milestone-changelog/ | ||
action.yml | ||
scripts/ | ||
changelog-command-validate.js | ||
workflows/ | ||
changelog-command-dispatch.yml | ||
changelog-command.yml | ||
changelog.yml | ||
``` | ||
|
||
**Milestone changelog action** creates or updates a changelog PR for a given | ||
*open* milesone. It is used by two workflows. | ||
|
||
**Changelog workflow** re-generates all changelog PRs on push to the main | ||
branch. | ||
|
||
**Changelog command dispatch** handles `/changelog` command and dispathes the | ||
`changelog-command` repository event. | ||
|
||
**Changelog command** handles the `changelog-command` in the contet of a | ||
changelog pull request, and calls the action to update the PR in-place with | ||
fresh changelog. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
name: Changelog | ||
on: | ||
pull_request: | ||
types: | ||
- "closed" | ||
- "edited" | ||
branches: | ||
- "main" | ||
issues: | ||
types: | ||
- "milestoned" | ||
# We don't track "demilestoned" event type. If we did, changing a milestone would always | ||
# trigger duplicating workflows one of which would fail due to concurrent updates of the same | ||
# changelog branch. We hope, that milestones change to other milestones, and are not removed | ||
# at all. To update changelog, one should call `/changelog` command in a changelog PR. | ||
# - "demilestoned" | ||
jobs: | ||
filter: | ||
name: Filter Issues | ||
runs-on: ubuntu-latest | ||
# In all cases: | ||
# skipping the changelog PR itself, provided it is detected by label | ||
# | ||
# Conditions | ||
# 1. pull_request is edited or merged | ||
# OR | ||
# 2. milestone is set/removed (via issue api), we check the related PR in step | ||
if: | | ||
( | ||
github.event.pull_request && | ||
github.event.pull_request.state == 'closed' && | ||
github.event.pull_request.merged && | ||
github.event.pull_request.milestone.state == 'open' && | ||
!contains(github.event.issue.labels.*.name, 'changelog') | ||
) || ( | ||
(github.event.action == 'milestoned' || github.event.action == 'demilestoned') && | ||
github.event.issue.pull_request && | ||
!contains(github.event.issue.labels.*.name, 'changelog') | ||
) | ||
steps: | ||
- name: Check PR | ||
id: pr | ||
uses: actions/github-script@v5 | ||
with: | ||
script: | | ||
// 'demilestoned' should also be checked if used as trigger | ||
if (context.eventName === 'milestoned') { | ||
const { data: pr } = await github.rest.pulls.get({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
pull_number: context.issue.number, | ||
}); | ||
if (pr.state !== 'closed' || !pr.merged) { | ||
// Skip this PR, the change is not applied yet | ||
return; | ||
} | ||
} | ||
core.setOutput("ok", "ok") | ||
outputs: | ||
ok: steps.pr.outputs.ok | ||
|
||
milestones: | ||
if: needs.filter.outputs.ok == "ok" | ||
name: Open Milestones | ||
runs-on: ubuntu-latest | ||
needs: filter | ||
steps: | ||
- name: Find Open Milestones | ||
id: milestones | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.CHANGELOG_ACCESS_TOKEN }} | ||
run: | | ||
# We expect the number of simultaneously open milestones will not exceed 10. | ||
# https://docs.github.com/en/rest/reference/issues#milestones | ||
milestones="$(gh api 'repos/${{ github.repository }}/milestones?state=open&per_page=100' | ||
count="$(echo $milestones | jq '. | length')" | ||
echo "::set-output name=list::${milestones}" | ||
echo "::set-output name=count::${count}" | ||
outputs: | ||
list: ${{ steps.milestones.outputs.list }} | ||
count: ${{ steps.milestones.outputs.count }} | ||
|
||
chanegelogs: | ||
if: needs.milestones.outputs.count > 0 | ||
name: Changelog ${{ matrix.milestone.title }} | ||
runs-on: ubuntu-latest | ||
needs: milestones | ||
strategy: | ||
matrix: | ||
milestone: ${{ fromJSON( needs.milestones.outputs.list ) }} | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
|
||
- name: Create changelog | ||
uses: ./.github/actions/milestone-changelog | ||
with: | ||
milestone: ${{ toJSON( matrix.milestone ) }} | ||
token: ${{ secrets.CHANGELOG_ACCESS_TOKEN }} |