Skip to content

Commit 1590dc6

Browse files
author
Alexander Melnyk
committed
Merge branch 'develop' of github.com:awslabs/aws-lambda-powertools-python into develop
2 parents 2ded8a6 + 24d7b5f commit 1590dc6

File tree

89 files changed

+4231
-1737
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+4231
-1737
lines changed

.chglog/CHANGELOG.tpl.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
<!-- changelog is partially generated, so it doesn't follow headings and required structure, so we disable it. -->
2+
<!-- markdownlint-disable -->
3+
14
{{ if .Versions -}}
25
<a name="unreleased"></a>
3-
## Unreleased
6+
# Unreleased
47

58
{{ if .Unreleased.CommitGroups -}}
69
{{ range .Unreleased.CommitGroups -}}
7-
### {{ .Title }}
10+
## {{ .Title }}
811

912
{{ range .Commits -}}
1013
* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
@@ -17,22 +20,23 @@
1720
<a name="{{ .Tag.Name }}"></a>
1821
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
1922
{{ range .CommitGroups -}}
20-
### {{ .Title }}
23+
24+
## {{ .Title }}
2125

2226
{{ range .Commits -}}
2327
* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
2428
{{ end }}
2529
{{ end -}}
2630

2731
{{- if .RevertCommits -}}
28-
### Reverts
32+
## Reverts
2933
{{ range .RevertCommits -}}
3034
* {{ .Revert.Header }}
3135
{{ end }}
3236
{{ end -}}
3337

3438
{{- if .MergeCommits -}}
35-
### Pull Requests
39+
## Pull Requests
3640

3741
{{ range .MergeCommits -}}
3842
* {{ .Header }}
@@ -41,7 +45,7 @@
4145

4246
{{- if .NoteGroups -}}
4347
{{ range .NoteGroups -}}
44-
### {{ .Title }}
48+
## {{ .Title }}
4549
{{ range .Notes }}
4650
{{ .Body }}
4751
{{ end }}

.chglog/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ options:
3232
notes:
3333
keywords:
3434
- BREAKING CHANGE
35+
# issues:
36+
# prefix:
37+
# - #

.github/mergify.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
# - name: Automatic merge ⬇️ on approval ✔
2424
# conditions:
25-
# - base!=master
2625
# - "#approved-reviews-by>=2"
2726
# actions:
2827
# queue:

.github/scripts/constants.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module.exports = Object.freeze({
2+
/** @type {string} */
3+
// Values: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request
4+
"PR_ACTION": process.env.PR_ACTION?.replace(/"/g, '') || "",
5+
6+
/** @type {string} */
7+
"PR_AUTHOR": process.env.PR_AUTHOR?.replace(/"/g, '') || "",
8+
9+
/** @type {string} */
10+
"PR_BODY": process.env.PR_BODY || "",
11+
12+
/** @type {string} */
13+
"PR_TITLE": process.env.PR_TITLE || "",
14+
15+
/** @type {number} */
16+
"PR_NUMBER": process.env.PR_NUMBER || 0,
17+
18+
/** @type {string} */
19+
"PR_IS_MERGED": process.env.PR_IS_MERGED || "false",
20+
21+
/** @type {string} */
22+
"LABEL_BLOCK": "do-not-merge",
23+
24+
/** @type {string} */
25+
"LABEL_BLOCK_REASON": "need-issue",
26+
27+
/** @type {string} */
28+
"LABEL_PENDING_RELEASE": "pending-release",
29+
30+
/** @type {string} */
31+
"HANDLE_MAINTAINERS_TEAM": "@awslabs/aws-lambda-powertools-python",
32+
33+
/** @type {string[]} */
34+
"IGNORE_AUTHORS": ["dependabot[bot]", "markdownify[bot]"],
35+
36+
/** @type {string[]} */
37+
"AREAS": [
38+
"tracer",
39+
"metrics",
40+
"utilities",
41+
"logger",
42+
"event_handlers",
43+
"middleware_factory",
44+
"idempotency",
45+
"event_sources",
46+
"feature_flags",
47+
"parameters",
48+
"batch",
49+
"parser",
50+
"validator",
51+
"jmespath_util",
52+
"lambda-layers",
53+
],
54+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module.exports = async ({github, context, core}) => {
2+
const fs = require('fs');
3+
4+
const workflowRunId = process.env.WORKFLOW_ID;
5+
core.info(`Listing artifacts for workflow run ${workflowRunId}`);
6+
7+
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
8+
owner: context.repo.owner,
9+
repo: context.repo.repo,
10+
run_id: workflowRunId,
11+
});
12+
13+
const matchArtifact = artifacts.data.artifacts.filter(artifact => artifact.name == "pr")[0];
14+
15+
core.info(`Downloading artifacts for workflow run ${workflowRunId}`);
16+
const artifact = await github.rest.actions.downloadArtifact({
17+
owner: context.repo.owner,
18+
repo: context.repo.repo,
19+
artifact_id: matchArtifact.id,
20+
archive_format: 'zip',
21+
});
22+
23+
core.info("Saving artifact found", artifact);
24+
25+
fs.writeFileSync('pr.zip', Buffer.from(artifact.data));
26+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const {
2+
PR_ACTION,
3+
PR_AUTHOR,
4+
PR_BODY,
5+
PR_NUMBER,
6+
IGNORE_AUTHORS,
7+
LABEL_BLOCK,
8+
LABEL_BLOCK_REASON
9+
} = require("./constants")
10+
11+
module.exports = async ({github, context, core}) => {
12+
if (IGNORE_AUTHORS.includes(PR_AUTHOR)) {
13+
return core.notice("Author in IGNORE_AUTHORS list; skipping...")
14+
}
15+
16+
if (PR_ACTION != "opened") {
17+
return core.notice("Only newly open PRs are labelled to avoid spam; skipping")
18+
}
19+
20+
const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?<issue>\d+)/;
21+
const isMatch = RELATED_ISSUE_REGEX.exec(PR_BODY);
22+
if (isMatch == null) {
23+
core.info(`No related issue found, maybe the author didn't use the template but there is one.`)
24+
25+
let msg = "No related issues found. Please ensure there is an open issue related to this change to avoid significant delays or closure.";
26+
await github.rest.issues.createComment({
27+
owner: context.repo.owner,
28+
repo: context.repo.repo,
29+
body: msg,
30+
issue_number: PR_NUMBER,
31+
});
32+
33+
return await github.rest.issues.addLabels({
34+
issue_number: PR_NUMBER,
35+
owner: context.repo.owner,
36+
repo: context.repo.repo,
37+
labels: [LABEL_BLOCK, LABEL_BLOCK_REASON]
38+
})
39+
}
40+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const { PR_NUMBER, PR_TITLE, AREAS } = require("./constants")
2+
3+
module.exports = async ({github, context, core}) => {
4+
const FEAT_REGEX = /feat(\((.+)\))?(:.+)/
5+
const BUG_REGEX = /(fix|bug)(\((.+)\))?(:.+)/
6+
const DOCS_REGEX = /(docs|doc)(\((.+)\))?(:.+)/
7+
const CHORE_REGEX = /(chore)(\((.+)\))?(:.+)/
8+
const DEPRECATED_REGEX = /(deprecated)(\((.+)\))?(:.+)/
9+
const REFACTOR_REGEX = /(refactor)(\((.+)\))?(:.+)/
10+
11+
const labels = {
12+
"feature": FEAT_REGEX,
13+
"bug": BUG_REGEX,
14+
"documentation": DOCS_REGEX,
15+
"internal": CHORE_REGEX,
16+
"enhancement": REFACTOR_REGEX,
17+
"deprecated": DEPRECATED_REGEX,
18+
}
19+
20+
// Maintenance: We should keep track of modified PRs in case their titles change
21+
let miss = 0;
22+
try {
23+
for (const label in labels) {
24+
const matcher = new RegExp(labels[label])
25+
const matches = matcher.exec(PR_TITLE)
26+
if (matches != null) {
27+
core.info(`Auto-labeling PR ${PR_NUMBER} with ${label}`)
28+
29+
await github.rest.issues.addLabels({
30+
issue_number: PR_NUMBER,
31+
owner: context.repo.owner,
32+
repo: context.repo.repo,
33+
labels: [label]
34+
})
35+
36+
const area = matches[2]; // second capture group contains the area
37+
if (AREAS.indexOf(area) > -1) {
38+
core.info(`Auto-labeling PR ${PR_NUMBER} with area ${area}`);
39+
await github.rest.issues.addLabels({
40+
issue_number: PR_NUMBER,
41+
owner: context.repo.owner,
42+
repo: context.repo.repo,
43+
labels: [`area/${area}`],
44+
});
45+
} else {
46+
core.debug(`'${PR_TITLE}' didn't match any known area.`);
47+
}
48+
49+
return;
50+
} else {
51+
core.debug(`'${PR_TITLE}' didn't match '${label}' semantic.`)
52+
miss += 1
53+
}
54+
}
55+
} finally {
56+
if (miss == Object.keys(labels).length) {
57+
core.notice(`PR ${PR_NUMBER} title '${PR_TITLE}' doesn't follow semantic titles; skipping...`)
58+
}
59+
}
60+
}

.github/scripts/label_related_issue.js

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,54 @@
1-
module.exports = async ({github, context}) => {
2-
const prBody = context.payload.body;
3-
const prNumber = context.payload.number;
4-
const releaseLabel = process.env.RELEASE_LABEL;
5-
const maintainersTeam = process.env.MAINTAINERS_TEAM
1+
const {
2+
PR_AUTHOR,
3+
PR_BODY,
4+
PR_NUMBER,
5+
IGNORE_AUTHORS,
6+
LABEL_PENDING_RELEASE,
7+
HANDLE_MAINTAINERS_TEAM,
8+
PR_IS_MERGED,
9+
} = require("./constants")
10+
11+
module.exports = async ({github, context, core}) => {
12+
if (IGNORE_AUTHORS.includes(PR_AUTHOR)) {
13+
return core.notice("Author in IGNORE_AUTHORS list; skipping...")
14+
}
15+
16+
if (PR_IS_MERGED == "false") {
17+
return core.notice("Only merged PRs to avoid spam; skipping")
18+
}
619

720
const RELATED_ISSUE_REGEX = /Issue number:[^\d\r\n]+(?<issue>\d+)/;
821

9-
const isMatch = RELATED_ISSUE_REGEX.exec(prBody);
10-
if (!isMatch) {
11-
core.setFailed(`Unable to find related issue for PR number ${prNumber}.\n\n Body details: ${prBody}`);
12-
return await github.rest.issues.createComment({
22+
const isMatch = RELATED_ISSUE_REGEX.exec(PR_BODY);
23+
24+
try {
25+
if (!isMatch) {
26+
core.setFailed(`Unable to find related issue for PR number ${PR_NUMBER}.\n\n Body details: ${PR_BODY}`);
27+
return await github.rest.issues.createComment({
28+
owner: context.repo.owner,
29+
repo: context.repo.repo,
30+
body: `${HANDLE_MAINTAINERS_TEAM} No related issues found. Please ensure '${LABEL_PENDING_RELEASE}' label is applied before releasing.`,
31+
issue_number: PR_NUMBER,
32+
});
33+
}
34+
} catch (error) {
35+
core.setFailed(`Unable to create comment on PR number ${PR_NUMBER}.\n\n Error details: ${error}`);
36+
throw new Error(error);
37+
}
38+
39+
const { groups: {issue} } = isMatch
40+
41+
try {
42+
core.info(`Auto-labeling related issue ${issue} for release`)
43+
await github.rest.issues.addLabels({
44+
issue_number: issue,
1345
owner: context.repo.owner,
1446
repo: context.repo.repo,
15-
body: `${maintainersTeam} No related issues found. Please ensure '${releaseLabel}' label is applied before releasing.`,
16-
issue_number: prNumber,
17-
});
47+
labels: [LABEL_PENDING_RELEASE]
48+
})
49+
} catch (error) {
50+
core.setFailed(`Is this issue number (${issue}) valid? Perhaps a discussion?`);
51+
throw new Error(error);
1852
}
1953

2054
const { groups: {relatedIssueNumber} } = isMatch

.github/workflows/post_release.js renamed to .github/scripts/post_release.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ const notifyRelease = async ({
100100

101101
// context: https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts
102102
module.exports = async ({ github, context }) => {
103-
const { RELEASE_TAG_VERSION } = process.env;
104-
console.log(`Running post-release script for ${RELEASE_TAG_VERSION} version`);
103+
const { RELEASE_VERSION } = process.env;
104+
console.log(`Running post-release script for ${RELEASE_VERSION} version`);
105105

106106
await notifyRelease({
107107
gh_client: github,
108108
owner: context.repo.owner,
109109
repository: context.repo.repo,
110-
release_version: RELEASE_TAG_VERSION,
110+
release_version: RELEASE_VERSION,
111111
});
112112
};

.github/scripts/save_pr_details.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = async ({context, core}) => {
2+
const fs = require('fs');
3+
const filename = "pr.txt";
4+
5+
try {
6+
fs.writeFileSync(`./${filename}`, JSON.stringify(context.payload));
7+
8+
return `PR successfully saved ${filename}`
9+
} catch (err) {
10+
core.setFailed("Failed to save PR details");
11+
console.error(err);
12+
}
13+
}

.github/workflows/auto-merge.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,21 @@ jobs:
1818
with:
1919
github-token: "${{ secrets.GITHUB_TOKEN }}"
2020
- name: Enable auto-merge for mypy-boto3 stubs Dependabot PRs
21-
if: ${{contains(steps.metadata.outputs.dependency-names, 'mypy-boto3')}} # && steps.metadata.outputs.update-type == 'version-update:semver-patch'
21+
if: ${{ contains(steps.metadata.outputs.dependency-names, 'mypy-boto3') && steps.metadata.outputs.update-type != 'version-update:semver-major' }}
22+
run: gh pr merge --auto --squash "$PR_URL"
23+
env:
24+
PR_URL: ${{github.event.pull_request.html_url}}
25+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
26+
# Maintenance: Experiment with literal array (toJSON('["dep1", "dep2"]')) to ease extending it
27+
- name: Enable auto-merge for CDK Construct Lambda Layer Dependabot PRs
28+
if: ${{ contains(steps.metadata.outputs.dependency-names, 'cdk-lambda-powertools-python-layer') && steps.metadata.outputs.update-type != 'version-update:semver-major' }}
29+
run: gh pr merge --auto --squash "$PR_URL"
30+
env:
31+
PR_URL: ${{github.event.pull_request.html_url}}
32+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
33+
# Maintenance: Revisit if CDK Constructs make breaking changes like CDK v1
34+
- name: Enable auto-merge for CDK Lib Construct
35+
if: ${{ contains(steps.metadata.outputs.dependency-names, 'aws-cdk-lib') && steps.metadata.outputs.update-type != 'version-update:semver-major' }}
2236
run: gh pr merge --auto --squash "$PR_URL"
2337
env:
2438
PR_URL: ${{github.event.pull_request.html_url}}

0 commit comments

Comments
 (0)