Skip to content

Commit 10ff0e7

Browse files
authored
Merge pull request #1 from corvus-dotnet/feature/pr-autoflow
Bump Endjin.PRAutoflow from 0.0.0 to 0.1.6 in .github/workflows
2 parents a8b81bc + cd0ed0e commit 10ff0e7

6 files changed

+441
-0
lines changed

.github/config/pr-autoflow.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"AUTO_MERGE_PACKAGE_WILDCARD_EXPRESSIONS": "[\"Endjin.*\",\"Corvus.*\"]",
3+
"AUTO_RELEASE_PACKAGE_WILDCARD_EXPRESSIONS": "[\"Corvus.AzureFunctionsKeepAlive\",\"Corvus.Configuration\",\"Corvus.ContentHandling\",\"Corvus.Deployment\",\"Corvus.DotLiquidAsync\",\"Corvus.EventStore\",\"Corvus.Extensions\",\"Corvus.Extensions.CosmosDb\",\"Corvus.Extensions.Newtonsoft.Json\",\"Corvus.Extensions.System.Text.Json\",\"Corvus.Identity\",\"Corvus.JsonSchema\",\"Corvus.Leasing\",\"Corvus.Monitoring\",\"Corvus.Retry\",\"Corvus.Storage\",\"Corvus.Tenancy\"]"
4+
}

.github/dependabot.yml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: nuget
4+
directory: /Solutions
5+
schedule:
6+
interval: daily
7+
open-pull-requests-limit: 10
8+

.github/workflows/auto_merge.yml

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: auto_merge
2+
on:
3+
check_run:
4+
types:
5+
# Check runs completing successfully can unblock the
6+
# corresponding pull requests and make them mergeable.
7+
- completed
8+
pull_request:
9+
types:
10+
# A closed pull request makes the checks on the other
11+
# pull request on the same base outdated.
12+
- closed
13+
# Adding the autosquash label to a pull request can
14+
# trigger an update or a merge.
15+
- labeled
16+
- synchronize
17+
pull_request_review:
18+
types:
19+
# Review approvals can unblock the pull request and
20+
# make it mergeable.
21+
- submitted
22+
# Success statuses can unblock the corresponding
23+
# pull requests and make them mergeable.
24+
status: {}
25+
workflow_run:
26+
workflows: [approve_and_label]
27+
types:
28+
- completed
29+
30+
permissions:
31+
contents: write
32+
pull-requests: write
33+
issues: write
34+
checks: read
35+
36+
jobs:
37+
38+
auto_merge:
39+
name: Auto-squash the PR
40+
runs-on: ubuntu-18.04
41+
steps:
42+
# This may not be strictly required, but should keep unmerged, closed PRs cleaner
43+
- name: Remove 'autosquash' label from closed PRs
44+
id: remove_autosquash_label_from_closed_prs
45+
uses: actions/github-script@v2
46+
with:
47+
github-token: '${{ secrets.GITHUB_TOKEN }}'
48+
script: |
49+
const pulls = await github.search.issuesAndPullRequests({
50+
q: 'is:pr is:closed label:autosquash',
51+
});
52+
core.info(`pulls: ${pulls.data.items}`)
53+
const repoUrl = `https://api.github.com/repos/${context.payload.repository.owner.login}/${context.payload.repository.name}`
54+
const prs_to_unlabel = pulls.data.items.
55+
filter(function (x) { return x.repository_url == repoUrl; }).
56+
map(p=>p.number);
57+
for (const i of prs_to_unlabel) {
58+
core.info(`Removing label 'autosquash' from issue #${i}`)
59+
github.issues.removeLabel({
60+
owner: context.payload.repository.owner.login,
61+
repo: context.payload.repository.name,
62+
issue_number: i,
63+
name: 'autosquash'
64+
});
65+
}
66+
- uses: endjin/[email protected]
67+
with:
68+
github_token: '${{ secrets.GITHUB_TOKEN }}'

.github/workflows/auto_release.yml

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
name: auto_release
2+
on:
3+
pull_request:
4+
types: [closed]
5+
6+
jobs:
7+
lookup_default_branch:
8+
runs-on: ubuntu-latest
9+
outputs:
10+
branch_name: ${{ steps.lookup_default_branch.outputs.result }}
11+
head_commit: ${{ steps.lookup_default_branch_head.outputs.result }}
12+
steps:
13+
- name: Lookup default branch name
14+
id: lookup_default_branch
15+
uses: actions/github-script@v2
16+
with:
17+
github-token: ${{ secrets.GITHUB_TOKEN }}
18+
result-encoding: string
19+
script: |
20+
const repo = await github.repos.get({
21+
owner: context.payload.repository.owner.login,
22+
repo: context.payload.repository.name
23+
});
24+
return repo.data.default_branch
25+
- name: Display default_branch_name
26+
run: |
27+
echo "default_branch_name : ${{ steps.lookup_default_branch.outputs.result }}"
28+
29+
- name: Lookup HEAD commit on default branch
30+
id: lookup_default_branch_head
31+
uses: actions/github-script@v2
32+
with:
33+
github-token: ${{ secrets.GITHUB_TOKEN }}
34+
result-encoding: string
35+
script: |
36+
const branch = await github.repos.getBranch({
37+
owner: context.payload.repository.owner.login,
38+
repo: context.payload.repository.name,
39+
branch: '${{ steps.lookup_default_branch.outputs.result }}'
40+
});
41+
return branch.data.commit.sha
42+
- name: Display default_branch_name_head
43+
run: |
44+
echo "default_branch_head_commit : ${{ steps.lookup_default_branch_head.outputs.result }}"
45+
46+
check_for_norelease_label:
47+
runs-on: ubuntu-latest
48+
outputs:
49+
no_release: ${{ steps.check_for_norelease_label.outputs.result }}
50+
steps:
51+
- name: Check for 'no_release' label on PR
52+
id: check_for_norelease_label
53+
uses: actions/github-script@v2
54+
with:
55+
github-token: ${{ secrets.GITHUB_TOKEN }}
56+
script: |
57+
const labels = await github.issues.listLabelsOnIssue({
58+
owner: context.payload.repository.owner.login,
59+
repo: context.payload.repository.name,
60+
issue_number: context.payload.number
61+
});
62+
core.info("labels: " + JSON.stringify(labels.data))
63+
if ( labels.data.map(l => l.name).includes("no_release") ) {
64+
core.info("Label found")
65+
return true
66+
}
67+
return false
68+
- name: Display 'no_release' status
69+
run: |
70+
echo "no_release: ${{ steps.check_for_norelease_label.outputs.result }}"
71+
72+
check_ready_to_release:
73+
runs-on: ubuntu-latest
74+
needs: [check_for_norelease_label,lookup_default_branch]
75+
if: |
76+
needs.check_for_norelease_label.outputs.no_release == 'false'
77+
outputs:
78+
no_open_prs: ${{ steps.watch_dependabot_prs.outputs.is_complete }}
79+
pending_release_pr_list: ${{ steps.get_release_pending_pr_list.outputs.result }}
80+
ready_to_release: ${{ steps.watch_dependabot_prs.outputs.is_complete == 'True' && steps.get_release_pending_pr_list.outputs.is_release_pending }}
81+
steps:
82+
- name: Get Open PRs
83+
id: get_open_pr_list
84+
uses: actions/github-script@v2
85+
with:
86+
github-token: ${{ secrets.GITHUB_TOKEN }}
87+
# find all open PRs that are targetting the default branch (i.e. main/master)
88+
# return their titles, so they can parsed later to determine if they are
89+
# Dependabot PRs and whether we should wait for them to be auto-merged before
90+
# allowing a release event.
91+
script: |
92+
const pulls = await github.pulls.list({
93+
owner: context.payload.repository.owner.login,
94+
repo: context.payload.repository.name,
95+
state: 'open',
96+
base: '${{ needs.lookup_default_branch.outputs.branch_name }}'
97+
});
98+
return JSON.stringify(pulls.data.map(p=>p.title))
99+
result-encoding: string
100+
- name: Display open_pr_list
101+
run: |
102+
echo "open_pr_list : ${{ steps.get_open_pr_list.outputs.result }}"
103+
104+
- name: Get 'pending_release' PRs
105+
id: get_release_pending_pr_list
106+
uses: actions/github-script@v2
107+
with:
108+
github-token: ${{ secrets.GITHUB_TOKEN }}
109+
script: |
110+
const pulls = await github.search.issuesAndPullRequests({
111+
q: 'is:pr is:merged label:pending_release',
112+
});
113+
core.info(`pulls: ${pulls.data.items}`)
114+
const repoUrl = `https://api.github.com/repos/${context.payload.repository.owner.login}/${context.payload.repository.name}`
115+
const release_pending_prs = pulls.data.items.
116+
filter(function (x) { return x.repository_url == repoUrl; }).
117+
map(p=>p.number);
118+
core.info(`release_pending_prs: ${release_pending_prs}`)
119+
core.setOutput('is_release_pending', (release_pending_prs.length > 0))
120+
return JSON.stringify(release_pending_prs)
121+
result-encoding: string
122+
- name: Display release_pending_pr_list
123+
run: |
124+
echo "release_pending_pr_list : ${{ steps.get_release_pending_pr_list.outputs.result }}"
125+
echo "is_release_pending : ${{ steps.get_release_pending_pr_list.outputs.is_release_pending }}"
126+
127+
- uses: actions/checkout@v2
128+
- name: Read pr-autoflow configuration
129+
id: get_pr_autoflow_config
130+
uses: endjin/pr-autoflow/actions/read-configuration@v1
131+
with:
132+
config_file: .github/config/pr-autoflow.json
133+
134+
- name: Watch Dependabot PRs
135+
id: watch_dependabot_prs
136+
uses: endjin/pr-autoflow/actions/dependabot-pr-watcher@v1
137+
with:
138+
pr_titles: ${{ steps.get_open_pr_list.outputs.result }}
139+
package_wildcard_expressions: ${{ steps.get_pr_autoflow_config.outputs.AUTO_MERGE_PACKAGE_WILDCARD_EXPRESSIONS }}
140+
max_semver_increment: minor
141+
verbose_mode: 'False'
142+
143+
- name: Display job outputs
144+
run: |
145+
echo "no_open_prs: ${{ steps.watch_dependabot_prs.outputs.is_complete }}"
146+
echo "pending_release_pr_list: ${{ steps.get_release_pending_pr_list.outputs.result }}"
147+
echo "ready_to_release : ${{ steps.watch_dependabot_prs.outputs.is_complete == 'True' && steps.get_release_pending_pr_list.outputs.is_release_pending }}"
148+
149+
tag_for_release:
150+
runs-on: ubuntu-latest
151+
needs: [check_ready_to_release,lookup_default_branch]
152+
if: |
153+
needs.check_ready_to_release.outputs.ready_to_release == 'true'
154+
steps:
155+
- uses: actions/setup-dotnet@v1
156+
with:
157+
dotnet-version: '3.1.x'
158+
159+
- uses: actions/checkout@v2
160+
with:
161+
# ensure we are creating the release tag on the default branch
162+
ref: ${{ needs.lookup_default_branch.outputs.branch_name }}
163+
fetch-depth: 0
164+
165+
- name: Install GitVersion
166+
run: |
167+
dotnet tool install -g GitVersion.Tool --version 5.6.6
168+
echo "/github/home/.dotnet/tools" >> $GITHUB_PATH
169+
- name: Run GitVersion
170+
id: run_gitversion
171+
run: |
172+
pwsh -noprofile -c 'dotnet-gitversion /diag'
173+
pwsh -noprofile -c '(dotnet-gitversion | ConvertFrom-Json).psobject.properties | % { echo ("::set-output name={0}::{1}" -f $_.name, $_.value) }'
174+
175+
- name: Generate token
176+
id: generate_token
177+
uses: tibdex/github-app-token@v1
178+
with:
179+
app_id: ${{ secrets.ENDJIN_BOT_APP_ID }}
180+
private_key: ${{ secrets.ENDJIN_BOT_PRIVATE_KEY }}
181+
182+
- name: Create SemVer tag
183+
uses: actions/github-script@v2
184+
with:
185+
github-token: ${{ steps.generate_token.outputs.token }}
186+
script: |
187+
const uri_path = '/repos/' + context.payload.repository.owner.login + '/' + context.payload.repository.name + '/git/refs'
188+
const tag = await github.request(('POST ' + uri_path), {
189+
owner: context.payload.repository.owner.login,
190+
repo: context.payload.repository.name,
191+
ref: 'refs/tags/${{ steps.run_gitversion.outputs.MajorMinorPatch }}',
192+
sha: '${{ needs.lookup_default_branch.outputs.head_commit }}'
193+
})
194+
195+
- name: Remove 'release_pending' label from PRs
196+
id: remove_pending_release_labels
197+
uses: actions/github-script@v2
198+
with:
199+
github-token: '${{ steps.generate_token.outputs.token }}'
200+
script: |
201+
core.info('PRs to unlabel: ${{ needs.check_ready_to_release.outputs.pending_release_pr_list }}')
202+
const pr_list = JSON.parse('${{ needs.check_ready_to_release.outputs.pending_release_pr_list }}')
203+
core.info(`pr_list: ${pr_list}`)
204+
for (const i of pr_list) {
205+
core.info(`Removing label 'pending_release' from issue #${i}`)
206+
github.issues.removeLabel({
207+
owner: context.payload.repository.owner.login,
208+
repo: context.payload.repository.name,
209+
issue_number: i,
210+
name: 'pending_release'
211+
});
212+
}

0 commit comments

Comments
 (0)