danger-dangermattic 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/README.md +71 -0
- data/.github/workflows/reusable-check-labels-on-issues.yml +19 -11
- data/.github/workflows/reusable-retry-buildkite-step-on-events.yml +13 -7
- data/.github/workflows/reusable-run-danger.yml +8 -6
- data/CHANGELOG.md +37 -3
- data/Gemfile.lock +36 -44
- data/README.md +27 -0
- data/Rakefile +88 -1
- data/danger-dangermattic.gemspec +1 -1
- data/lib/dangermattic/gem_version.rb +1 -1
- data/lib/dangermattic/plugins/manifest_pr_checker.rb +30 -6
- data/lib/dangermattic/plugins/view_changes_checker.rb +3 -3
- data/rakelib/changelog_parser.rake +108 -0
- data/rakelib/console.rake +46 -0
- data/rakelib/git_helpers.rake +39 -0
- data/spec/manifest_pr_checker_spec.rb +67 -26
- data/spec/spec_helper.rb +0 -2
- data/spec/view_changes_checker_spec.rb +10 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '094bf199c42dcc05762611116e76958dd679f4fd528aee911a0f2e56cef7ec1e'
|
4
|
+
data.tar.gz: 0ea8f18010582cf5d91d0f75a5e7aeadf677fce8bf46fe9d006f0b2cb5985c15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 477a907cde572da9e3c5a76eee541e38b82a240a12b8691dec4c2a1697ebb7a664b80836d5eca45513d26a95e270e67b9cbcde08562f9abb691684fa47a21b93
|
7
|
+
data.tar.gz: cc0e1a03b5ddb87b3a7961665f7318feceaff2efe437d261b484c5fad1455a78872c719baee93642d0698dc24314bbc4a22cdb9218c8bc80c7ae6997bfbf55f3
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Dangermattic GitHub Workflows Documentation
|
2
|
+
|
3
|
+
We provide reusable GitHub workflows to be used with Dangermattic.
|
4
|
+
Each workflow is designed to be called from other workflows using the `workflow_call` event and input parameters.
|
5
|
+
All jobs are run on `ubuntu-latest`.
|
6
|
+
|
7
|
+
## Check Labels on Issues
|
8
|
+
|
9
|
+
**File:** `workflows/reusable-check-labels-on-issues.yml`
|
10
|
+
|
11
|
+
This workflow is an independent check (not using Danger) to verify if the labels on an issue match specified regex patterns.
|
12
|
+
|
13
|
+
### Inputs:
|
14
|
+
- `label-format-list`: JSON list of regex formats expected for the labels (default: `[".*"]`)
|
15
|
+
- `label-error-message`: Error message when labels don't match
|
16
|
+
- `label-success-message`: Success message when labels match
|
17
|
+
- `cancel-running-jobs`: Cancel in-progress jobs when new ones are created (default: `true`)
|
18
|
+
|
19
|
+
### Secrets:
|
20
|
+
- `github-token`: Required GitHub token
|
21
|
+
|
22
|
+
### Job: `check-issue-labels`
|
23
|
+
- Permissions: `issues: write`
|
24
|
+
- Main step: "🏷️ Check Issue Labels"
|
25
|
+
- Checks if issue labels match the specified regex patterns
|
26
|
+
- Posts a comment on the issue with success or error message
|
27
|
+
|
28
|
+
## Retry Buildkite Step on Pull Request Events
|
29
|
+
|
30
|
+
**File:** `workflows/reusable-retry-buildkite-step-on-events.yml`
|
31
|
+
|
32
|
+
This workflow retries a specific job in a Buildkite pipeline.
|
33
|
+
|
34
|
+
### Inputs:
|
35
|
+
- `org-slug`: Buildkite organization slug
|
36
|
+
- `pipeline-slug`: Slug of the Buildkite pipeline to be run
|
37
|
+
- `retry-step-key`: Key of the Buildkite job to be retried
|
38
|
+
- `build-commit-sha`: Commit to check for running Buildkite Builds
|
39
|
+
- `cancel-running-github-jobs`: Cancel in-progress GitHub jobs when new ones are created (default: `true`)
|
40
|
+
|
41
|
+
### Secrets:
|
42
|
+
- `buildkite-api-token`: Required Buildkite API token
|
43
|
+
|
44
|
+
### Job: `retry-buildkite-job`
|
45
|
+
- Main step: "🔄 Retry job on the latest Buildkite Build"
|
46
|
+
- Retrieves the latest Buildkite build for the specified commit
|
47
|
+
- Identifies the job to retry based on the provided step key
|
48
|
+
- Retries the job if it's in an appropriate state (passed, failed, canceled, or finished)
|
49
|
+
|
50
|
+
## Run Danger on GitHub
|
51
|
+
|
52
|
+
**File:** `workflows/reusable-run-danger.yml`
|
53
|
+
|
54
|
+
This workflow runs Danger directly on GitHub Actions.
|
55
|
+
|
56
|
+
### Inputs:
|
57
|
+
- `remove-previous-comments`: Remove previous Danger comments and add a new one (default: `false`)
|
58
|
+
- `cancel-running-jobs`: Cancel in-progress jobs when new ones are created (default: `true`)
|
59
|
+
|
60
|
+
### Secrets:
|
61
|
+
- `github-token`: Required GitHub token
|
62
|
+
|
63
|
+
### Job: `dangermattic`
|
64
|
+
- Steps:
|
65
|
+
1. Checkout repository
|
66
|
+
2. Set up Ruby
|
67
|
+
3. Run Danger PR Check
|
68
|
+
- Executes Danger in read-only mode for forks and Dependabot PRs
|
69
|
+
- Runs Danger with full functionality for PRs where the configured token has access to the repo
|
70
|
+
|
71
|
+
These reusable workflows can be incorporated into other workflows in your repository to perform specific tasks related to issue labeling, Buildkite job management, and pull request checks using Danger.
|
@@ -1,30 +1,38 @@
|
|
1
|
+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
2
|
+
|
1
3
|
on:
|
2
4
|
workflow_call:
|
3
5
|
inputs:
|
4
6
|
label-format-list:
|
5
|
-
description:
|
6
|
-
default:
|
7
|
-
|
8
|
-
|
7
|
+
description: The Regex formats expected for the labels; must be a JSON list
|
8
|
+
default: |
|
9
|
+
[
|
10
|
+
".*"
|
11
|
+
]
|
9
12
|
type: string
|
10
13
|
required: false
|
11
14
|
label-error-message:
|
12
|
-
description:
|
13
|
-
default:
|
15
|
+
description: Error message to be posted when the labels set don't match the required list of formats.
|
16
|
+
default: At least one label is required.
|
14
17
|
type: string
|
15
18
|
required: false
|
16
19
|
label-success-message:
|
17
|
-
description:
|
18
|
-
default:
|
20
|
+
description: Message to be posted when the labels set fulfill the entire list of expected formats.
|
21
|
+
default: ✅ Yay, issue looks great!
|
19
22
|
type: string
|
20
23
|
required: false
|
24
|
+
cancel-running-jobs:
|
25
|
+
description: Cancel currently in progress jobs when new ones are added.
|
26
|
+
default: true
|
27
|
+
type: boolean
|
28
|
+
required: false
|
21
29
|
secrets:
|
22
30
|
github-token:
|
23
31
|
required: true
|
24
32
|
|
25
33
|
concurrency:
|
26
|
-
group:
|
27
|
-
cancel-in-progress:
|
34
|
+
group: ${{ github.workflow }}-${{ github.event.issue.number }}
|
35
|
+
cancel-in-progress: ${{ inputs.cancel-running-jobs }}
|
28
36
|
|
29
37
|
jobs:
|
30
38
|
check-issue-labels:
|
@@ -32,7 +40,7 @@ jobs:
|
|
32
40
|
permissions:
|
33
41
|
issues: write
|
34
42
|
steps:
|
35
|
-
- name:
|
43
|
+
- name: 🏷️ Check Issue Labels
|
36
44
|
env:
|
37
45
|
GITHUB_TOKEN: ${{ secrets.github-token }}
|
38
46
|
GH_REPO: ${{ github.repository }}
|
@@ -1,24 +1,26 @@
|
|
1
|
+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
2
|
+
|
1
3
|
on:
|
2
4
|
workflow_call:
|
3
5
|
inputs:
|
4
6
|
org-slug:
|
5
|
-
description:
|
7
|
+
description: Buildkite organization slug
|
6
8
|
required: true
|
7
9
|
type: string
|
8
10
|
pipeline-slug:
|
9
|
-
description:
|
11
|
+
description: Slug of the Buildkite pipeline to be run
|
10
12
|
required: true
|
11
13
|
type: string
|
12
14
|
retry-step-key:
|
13
|
-
description:
|
15
|
+
description: Key of the Buildkite job to be retried
|
14
16
|
required: true
|
15
17
|
type: string
|
16
18
|
build-commit-sha:
|
17
|
-
description:
|
19
|
+
description: Commit to check for running Buildkite Builds on. Usually github.event.pull_request.head.sha .
|
18
20
|
required: true
|
19
21
|
type: string
|
20
22
|
cancel-running-github-jobs:
|
21
|
-
description:
|
23
|
+
description: Cancel currently in progress Github jobs when new ones are added.
|
22
24
|
default: true
|
23
25
|
type: boolean
|
24
26
|
required: false
|
@@ -27,15 +29,19 @@ on:
|
|
27
29
|
required: true
|
28
30
|
|
29
31
|
concurrency:
|
30
|
-
group:
|
32
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
31
33
|
cancel-in-progress: ${{ inputs.cancel-running-github-jobs }}
|
32
34
|
|
33
35
|
jobs:
|
34
36
|
retry-buildkite-job:
|
35
37
|
runs-on: ubuntu-latest
|
36
38
|
steps:
|
37
|
-
- name:
|
39
|
+
- name: 🔄 Retry job on the latest Buildkite Build
|
40
|
+
env:
|
41
|
+
READ_ONLY_MODE: ${{ github.event.pull_request.head.repo.fork || github.actor == 'dependabot[bot]' }}
|
38
42
|
run: |
|
43
|
+
[ "$READ_ONLY_MODE" = true ] && { echo "ℹ️ Cannot retry a Buildkite job from GitHub when running in read-only mode (from a fork or a Dependabot Pull Request). Please find the Buildkite job and retry manually."; exit 0; }
|
44
|
+
|
39
45
|
ORG_SLUG="${{ inputs.org-slug }}"
|
40
46
|
PIPELINE_SLUG="${{ inputs.pipeline-slug }}"
|
41
47
|
RETRY_STEP_KEY="${{ inputs.retry-step-key }}"
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
2
|
+
|
1
3
|
on:
|
2
4
|
workflow_call:
|
3
5
|
inputs:
|
4
6
|
remove-previous-comments:
|
5
|
-
description:
|
7
|
+
description: Configures Danger to always remove previous comments and add a new one instead of editing the same comment.
|
6
8
|
default: false
|
7
9
|
type: boolean
|
8
10
|
required: false
|
9
11
|
cancel-running-jobs:
|
10
|
-
description:
|
12
|
+
description: Cancel currently in progress jobs when new ones are added.
|
11
13
|
default: true
|
12
14
|
type: boolean
|
13
15
|
required: false
|
@@ -16,22 +18,22 @@ on:
|
|
16
18
|
required: true
|
17
19
|
|
18
20
|
concurrency:
|
19
|
-
group:
|
21
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
20
22
|
cancel-in-progress: ${{ inputs.cancel-running-jobs }}
|
21
23
|
|
22
24
|
jobs:
|
23
25
|
dangermattic:
|
24
26
|
runs-on: ubuntu-latest
|
25
27
|
steps:
|
26
|
-
- name:
|
28
|
+
- name: 📥 Checkout Repo
|
27
29
|
uses: actions/checkout@v4
|
28
30
|
with:
|
29
31
|
fetch-depth: 100
|
30
|
-
- name:
|
32
|
+
- name: 💎 Ruby Setup
|
31
33
|
uses: ruby/setup-ruby@v1
|
32
34
|
with:
|
33
35
|
bundler-cache: true
|
34
|
-
- name:
|
36
|
+
- name: ☢️ Danger PR Check
|
35
37
|
env:
|
36
38
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
37
39
|
READ_ONLY_MODE: ${{ github.event.pull_request.head.repo.fork || github.actor == 'dependabot[bot]' }}
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,40 @@
|
|
2
2
|
|
3
3
|
---
|
4
4
|
|
5
|
+
## Trunk
|
6
|
+
|
7
|
+
### Breaking Changes
|
8
|
+
|
9
|
+
_None_
|
10
|
+
|
11
|
+
### New Features
|
12
|
+
|
13
|
+
_None_
|
14
|
+
|
15
|
+
### Bug Fixes
|
16
|
+
|
17
|
+
_None_
|
18
|
+
|
19
|
+
### Internal Changes
|
20
|
+
|
21
|
+
_None_
|
22
|
+
|
23
|
+
## 1.2.0
|
24
|
+
|
25
|
+
### New Features
|
26
|
+
|
27
|
+
- `manifest_pr_checker`: add check for `Package.resolved` using full paths [#86]
|
28
|
+
|
29
|
+
### Bug Fixes
|
30
|
+
|
31
|
+
- `view_changes_checker`: update GitHub assets URL regex to be less strict [#89]
|
32
|
+
|
33
|
+
## 1.1.2
|
34
|
+
|
35
|
+
### Internal Changes
|
36
|
+
|
37
|
+
- Bump Ruby dependencies [#76]
|
38
|
+
|
5
39
|
## 1.1.1
|
6
40
|
|
7
41
|
### Internal Changes
|
@@ -12,19 +46,19 @@
|
|
12
46
|
|
13
47
|
### New Features
|
14
48
|
|
15
|
-
- Reusable GitHub Workflow for retrying Buildkite jobs
|
49
|
+
- Reusable GitHub Workflow for retrying Buildkite jobs [#64]
|
16
50
|
|
17
51
|
## 1.0.2
|
18
52
|
|
19
53
|
### Bug Fixes
|
20
54
|
|
21
|
-
- Clean up and update dependencies.
|
55
|
+
- Clean up and update dependencies. [#62]
|
22
56
|
|
23
57
|
## 1.0.1
|
24
58
|
|
25
59
|
### Bug Fixes
|
26
60
|
|
27
|
-
- Fix `tracks_checker` plugin so that only additions / removals in a diff are considered in the check, therefore not including the context parts of the diff.
|
61
|
+
- Fix `tracks_checker` plugin so that only additions / removals in a diff are considered in the check, therefore not including the context parts of the diff. [#58]
|
28
62
|
|
29
63
|
## 1.0.0
|
30
64
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
danger-dangermattic (1.
|
4
|
+
danger-dangermattic (1.2.0)
|
5
5
|
danger (~> 9.4)
|
6
6
|
danger-plugin-api (~> 1.0)
|
7
7
|
danger-rubocop (~> 0.13)
|
@@ -10,8 +10,8 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
addressable (2.8.
|
14
|
-
public_suffix (>= 2.0.2, <
|
13
|
+
addressable (2.8.7)
|
14
|
+
public_suffix (>= 2.0.2, < 7.0)
|
15
15
|
ast (2.4.2)
|
16
16
|
base64 (0.2.0)
|
17
17
|
claide (1.1.0)
|
@@ -23,7 +23,8 @@ GEM
|
|
23
23
|
colored2 (3.1.2)
|
24
24
|
cork (0.3.0)
|
25
25
|
colored2 (~> 3.1)
|
26
|
-
danger (9.
|
26
|
+
danger (9.5.1)
|
27
|
+
base64 (~> 0.2)
|
27
28
|
claide (~> 1.0)
|
28
29
|
claide-plugins (>= 0.9.2)
|
29
30
|
colored2 (~> 3.1)
|
@@ -33,8 +34,8 @@ GEM
|
|
33
34
|
git (~> 1.13)
|
34
35
|
kramdown (~> 2.3)
|
35
36
|
kramdown-parser-gfm (~> 1.0)
|
36
|
-
no_proxy_fix
|
37
37
|
octokit (>= 4.0)
|
38
|
+
pstore (~> 0.1)
|
38
39
|
terminal-table (>= 1, < 4)
|
39
40
|
danger-plugin-api (1.0.0)
|
40
41
|
danger (> 2.0)
|
@@ -42,18 +43,21 @@ GEM
|
|
42
43
|
danger
|
43
44
|
rubocop (~> 1.0)
|
44
45
|
diff-lcs (1.5.1)
|
45
|
-
faraday (2.
|
46
|
-
faraday-net_http (>= 2.0, < 3.
|
46
|
+
faraday (2.12.0)
|
47
|
+
faraday-net_http (>= 2.0, < 3.4)
|
48
|
+
json
|
49
|
+
logger
|
47
50
|
faraday-http-cache (2.5.1)
|
48
51
|
faraday (>= 0.8)
|
49
|
-
faraday-net_http (3.
|
52
|
+
faraday-net_http (3.3.0)
|
50
53
|
net-http
|
51
|
-
ffi (1.
|
54
|
+
ffi (1.17.0)
|
55
|
+
ffi (1.17.0-arm64-darwin)
|
52
56
|
formatador (1.1.0)
|
53
57
|
git (1.19.1)
|
54
58
|
addressable (~> 2.8)
|
55
59
|
rchardet (~> 1.8)
|
56
|
-
guard (2.
|
60
|
+
guard (2.19.0)
|
57
61
|
formatador (>= 0.2.4)
|
58
62
|
listen (>= 2.7, < 4.0)
|
59
63
|
lumberjack (>= 1.0.12, < 2.0)
|
@@ -67,7 +71,7 @@ GEM
|
|
67
71
|
guard (~> 2.1)
|
68
72
|
guard-compat (~> 1.1)
|
69
73
|
rspec (>= 2.99.0, < 4.0)
|
70
|
-
json (2.7.
|
74
|
+
json (2.7.5)
|
71
75
|
kramdown (2.4.0)
|
72
76
|
rexml
|
73
77
|
kramdown-parser-gfm (1.1.0)
|
@@ -76,30 +80,30 @@ GEM
|
|
76
80
|
listen (3.9.0)
|
77
81
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
78
82
|
rb-inotify (~> 0.9, >= 0.9.10)
|
83
|
+
logger (1.6.1)
|
79
84
|
lumberjack (1.2.10)
|
80
85
|
method_source (1.1.0)
|
81
86
|
nap (1.1.0)
|
82
87
|
nenv (0.3.0)
|
83
88
|
net-http (0.4.1)
|
84
89
|
uri
|
85
|
-
no_proxy_fix (0.1.2)
|
86
90
|
notiffany (0.1.3)
|
87
91
|
nenv (~> 0.1)
|
88
92
|
shellany (~> 0.0)
|
89
|
-
octokit (
|
90
|
-
base64
|
93
|
+
octokit (9.2.0)
|
91
94
|
faraday (>= 1, < 3)
|
92
95
|
sawyer (~> 0.9)
|
93
96
|
open4 (1.3.4)
|
94
|
-
parallel (1.
|
95
|
-
parser (3.3.1
|
97
|
+
parallel (1.26.3)
|
98
|
+
parser (3.3.5.1)
|
96
99
|
ast (~> 2.4.1)
|
97
100
|
racc
|
98
101
|
pry (0.14.2)
|
99
102
|
coderay (~> 1.1)
|
100
103
|
method_source (~> 1.0)
|
101
|
-
|
102
|
-
|
104
|
+
pstore (0.1.3)
|
105
|
+
public_suffix (6.0.1)
|
106
|
+
racc (1.8.1)
|
103
107
|
rainbow (3.1.1)
|
104
108
|
rake (13.2.1)
|
105
109
|
rb-fsevent (0.11.2)
|
@@ -107,59 +111,47 @@ GEM
|
|
107
111
|
ffi (~> 1.0)
|
108
112
|
rchardet (1.8.0)
|
109
113
|
regexp_parser (2.9.2)
|
110
|
-
rexml (3.
|
111
|
-
strscan (>= 3.0.9)
|
114
|
+
rexml (3.3.9)
|
112
115
|
rspec (3.13.0)
|
113
116
|
rspec-core (~> 3.13.0)
|
114
117
|
rspec-expectations (~> 3.13.0)
|
115
118
|
rspec-mocks (~> 3.13.0)
|
116
|
-
rspec-core (3.13.
|
119
|
+
rspec-core (3.13.2)
|
117
120
|
rspec-support (~> 3.13.0)
|
118
|
-
rspec-expectations (3.13.
|
121
|
+
rspec-expectations (3.13.3)
|
119
122
|
diff-lcs (>= 1.2.0, < 2.0)
|
120
123
|
rspec-support (~> 3.13.0)
|
121
|
-
rspec-mocks (3.13.
|
124
|
+
rspec-mocks (3.13.2)
|
122
125
|
diff-lcs (>= 1.2.0, < 2.0)
|
123
126
|
rspec-support (~> 3.13.0)
|
124
127
|
rspec-support (3.13.1)
|
125
|
-
rubocop (1.
|
128
|
+
rubocop (1.68.0)
|
126
129
|
json (~> 2.3)
|
127
130
|
language_server-protocol (>= 3.17.0)
|
128
131
|
parallel (~> 1.10)
|
129
132
|
parser (>= 3.3.0.2)
|
130
133
|
rainbow (>= 2.2.2, < 4.0)
|
131
|
-
regexp_parser (>=
|
132
|
-
|
133
|
-
rubocop-ast (>= 1.31.1, < 2.0)
|
134
|
+
regexp_parser (>= 2.4, < 3.0)
|
135
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
134
136
|
ruby-progressbar (~> 1.7)
|
135
137
|
unicode-display_width (>= 2.4.0, < 3.0)
|
136
|
-
rubocop-ast (1.
|
138
|
+
rubocop-ast (1.33.0)
|
137
139
|
parser (>= 3.3.1.0)
|
138
|
-
rubocop-capybara (2.20.0)
|
139
|
-
rubocop (~> 1.41)
|
140
|
-
rubocop-factory_bot (2.25.1)
|
141
|
-
rubocop (~> 1.41)
|
142
140
|
rubocop-rake (0.6.0)
|
143
141
|
rubocop (~> 1.0)
|
144
|
-
rubocop-rspec (2.
|
145
|
-
rubocop (~> 1.
|
146
|
-
rubocop-capybara (~> 2.17)
|
147
|
-
rubocop-factory_bot (~> 2.22)
|
148
|
-
rubocop-rspec_rails (~> 2.28)
|
149
|
-
rubocop-rspec_rails (2.28.3)
|
150
|
-
rubocop (~> 1.40)
|
142
|
+
rubocop-rspec (3.2.0)
|
143
|
+
rubocop (~> 1.61)
|
151
144
|
ruby-progressbar (1.13.0)
|
152
145
|
sawyer (0.9.2)
|
153
146
|
addressable (>= 2.3.5)
|
154
147
|
faraday (>= 0.17.3, < 3)
|
155
148
|
shellany (0.0.1)
|
156
|
-
strscan (3.1.0)
|
157
149
|
terminal-table (3.0.2)
|
158
150
|
unicode-display_width (>= 1.1.1, < 3)
|
159
|
-
thor (1.3.
|
160
|
-
unicode-display_width (2.
|
161
|
-
uri (0.13.
|
162
|
-
yard (0.9.
|
151
|
+
thor (1.3.2)
|
152
|
+
unicode-display_width (2.6.0)
|
153
|
+
uri (0.13.1)
|
154
|
+
yard (0.9.37)
|
163
155
|
|
164
156
|
PLATFORMS
|
165
157
|
arm64-darwin-22
|
data/README.md
CHANGED
@@ -35,6 +35,10 @@ Once the main Gem is installed, all Dangermattic plugins are available in your `
|
|
35
35
|
|
36
36
|
All available plugins are defined here: https://github.com/Automattic/dangermattic/tree/trunk/lib/dangermattic/plugins
|
37
37
|
|
38
|
+
## GitHub Workflows
|
39
|
+
|
40
|
+
Dangermattic also provides some useful reusable GitHub workflows. For more information on available workflows and how to use them, please refer to the [Workflows README](.github/workflows/README.md).
|
41
|
+
|
38
42
|
## Development
|
39
43
|
|
40
44
|
- Clone the repo and run `bundle install` to setup dependencies
|
@@ -66,3 +70,26 @@ my_new_plugin_checker.check_method(param: my_param_value)
|
|
66
70
|
```
|
67
71
|
|
68
72
|
Please follow the existing naming convention for validation and check plugins: classes end with a `*Checker` suffix and the main validation methods are named with a `check_*` prefix.
|
73
|
+
|
74
|
+
## Releasing a new version
|
75
|
+
|
76
|
+
To create a new release of the Dangermattic gem, use the `new_release` Rake task:
|
77
|
+
|
78
|
+
```
|
79
|
+
bundle exec rake new_release
|
80
|
+
```
|
81
|
+
|
82
|
+
This task will:
|
83
|
+
|
84
|
+
1. Parse the `CHANGELOG.md` file to get the latest version and pending changes.
|
85
|
+
1. Prompt for the new version number.
|
86
|
+
1. Update the `VERSION` constant in the `gem_version.rb` file.
|
87
|
+
1. Update the `CHANGELOG.md` file with the new version.
|
88
|
+
1. Create a new branch, commit the changes, and push to GitHub.
|
89
|
+
1. Open a draft Pull Request for the release.
|
90
|
+
|
91
|
+
After running the task, follow the instructions provided to complete the release process:
|
92
|
+
|
93
|
+
1. Review and merge the Pull Request.
|
94
|
+
1. Create a GitHub release targeting the `trunk` branch, using the changelog content provided.
|
95
|
+
1. Publishing the GitHub release with a tag will trigger a CI workflow to publish the new gem version to RubyGems.
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ task all: %i[specs lint]
|
|
11
11
|
|
12
12
|
desc 'Ensure that the plugin passes `danger plugins lint`'
|
13
13
|
task :danger_lint do
|
14
|
-
sh
|
14
|
+
sh('bundle', 'exec', 'danger', 'plugins', 'lint')
|
15
15
|
end
|
16
16
|
|
17
17
|
desc 'Runs linting tasks: :rubocop and :danger_lint'
|
@@ -22,3 +22,90 @@ RSpec::Core::RakeTask.new(:specs)
|
|
22
22
|
|
23
23
|
desc 'Run RuboCop on the lib/specs directory'
|
24
24
|
RuboCop::RakeTask.new(:rubocop)
|
25
|
+
|
26
|
+
desc 'Generate the docs using YARD'
|
27
|
+
task :doc do
|
28
|
+
sh('bundle', 'exec', 'yard', 'doc')
|
29
|
+
# Open generated doc in browser
|
30
|
+
sh('open', 'yard-doc/index.html')
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Print stats about undocumented methods. Provide an optional path relative to 'lib/dangermattic/plugins' to only show stats for that subdirectory"
|
34
|
+
task :docstats, [:path] do |_, args|
|
35
|
+
path = File.join('lib/dangermattic/plugins', args[:path] || '.')
|
36
|
+
sh('yard', 'stats', '--list-undoc', path)
|
37
|
+
end
|
38
|
+
|
39
|
+
VERSION_FILE = File.join('lib', 'dangermattic', 'gem_version.rb')
|
40
|
+
|
41
|
+
desc 'Create a new version of the dangermattic gem'
|
42
|
+
task :new_release do
|
43
|
+
require_relative(VERSION_FILE)
|
44
|
+
|
45
|
+
parser = ChangelogParser.new(file: 'CHANGELOG.md')
|
46
|
+
latest_version = parser.parse_pending_section
|
47
|
+
|
48
|
+
## Print current info
|
49
|
+
Console.header "Current version is: #{Dangermattic::VERSION}"
|
50
|
+
Console.warning "Warning: Latest version number does not match latest version title in CHANGELOG (#{latest_version})!" unless latest_version == Dangermattic::VERSION
|
51
|
+
|
52
|
+
Console.header 'Pending CHANGELOG:'
|
53
|
+
changelog = parser.cleaned_pending_changelog_lines
|
54
|
+
Console.print_indented_lines(changelog)
|
55
|
+
|
56
|
+
## Prompt for next version number
|
57
|
+
guess = parser.guessed_next_semantic_version(current: Dangermattic::VERSION)
|
58
|
+
new_version = Console.prompt('New version to release', guess)
|
59
|
+
|
60
|
+
## Checkout branch, update files
|
61
|
+
GitHelper.check_or_create_branch(new_version)
|
62
|
+
Console.header 'Update `VERSION` constant in `version.rb`...'
|
63
|
+
update_version_constant(VERSION_FILE, new_version)
|
64
|
+
Console.header 'Updating CHANGELOG...'
|
65
|
+
parser.update_for_new_release(new_version: new_version)
|
66
|
+
|
67
|
+
# Commit and push
|
68
|
+
Console.header 'Commit and push changes...'
|
69
|
+
GitHelper.commit_files("Bumped to version #{new_version}", [VERSION_FILE, 'Gemfile.lock', 'CHANGELOG.md'])
|
70
|
+
|
71
|
+
Console.header 'Opening PR draft in your default browser...'
|
72
|
+
pr_body = <<~BODY
|
73
|
+
Releasing new version #{new_version}.
|
74
|
+
|
75
|
+
# What's Next
|
76
|
+
|
77
|
+
PR Author: Be sure to create and publish a GitHub Release pointing to `trunk` once this PR gets merged,
|
78
|
+
copy/pasting the following text as the GitHub Release's description:
|
79
|
+
```
|
80
|
+
#{changelog.join}
|
81
|
+
```
|
82
|
+
BODY
|
83
|
+
GitHelper.prepare_github_pr("release/#{new_version}", 'trunk', "Release #{new_version} into trunk", pr_body)
|
84
|
+
|
85
|
+
Console.info <<~INSTRUCTIONS
|
86
|
+
|
87
|
+
---------------
|
88
|
+
|
89
|
+
>>> WHAT'S NEXT
|
90
|
+
|
91
|
+
Once the PR is merged, publish a GitHub release for `#{new_version}`, targeting `trunk`,
|
92
|
+
with the following text as description:
|
93
|
+
|
94
|
+
```
|
95
|
+
#{changelog.join}
|
96
|
+
```
|
97
|
+
|
98
|
+
The publication of the new GitHub release will create a git tag, which in turn will trigger
|
99
|
+
a CI workflow that will take care of doing the `gem push` of the new version to RubyGems.
|
100
|
+
|
101
|
+
INSTRUCTIONS
|
102
|
+
end
|
103
|
+
|
104
|
+
def update_version_constant(version_file, new_version)
|
105
|
+
content = File.read(version_file)
|
106
|
+
content.gsub!(/VERSION = .*/, "VERSION = '#{new_version}'")
|
107
|
+
File.write(version_file, content)
|
108
|
+
|
109
|
+
# Updates the Gemfile.lock with the new dangermattic version
|
110
|
+
sh('bundle', 'install', '--quiet')
|
111
|
+
end
|
data/danger-dangermattic.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.required_ruby_version = '~> 3.2'
|
23
23
|
|
24
24
|
spec.add_dependency 'danger', '~> 9.4'
|
25
|
-
spec.
|
25
|
+
spec.add_dependency 'danger-plugin-api', '~> 1.0'
|
26
26
|
|
27
27
|
# Danger plugins
|
28
28
|
spec.add_dependency 'danger-rubocop', '~> 0.13'
|
@@ -29,6 +29,7 @@ module Danger
|
|
29
29
|
#
|
30
30
|
class ManifestPRChecker < Plugin
|
31
31
|
MESSAGE = '`%s` was changed without updating its corresponding `%s`. %s.'
|
32
|
+
SWIFT_INSTRUCTION = 'Please resolve the Swift packages as appropriate to your project setup (e.g. in Xcode or by running `swift package resolve`)'
|
32
33
|
|
33
34
|
# Performs all the checks, asserting that changes on `Gemfile`, `Podfile` and `Package.swift` must have corresponding
|
34
35
|
# lock file changes.
|
@@ -46,7 +47,6 @@ module Danger
|
|
46
47
|
#
|
47
48
|
# @param report_type [Symbol] (optional) The type of report for the message. Types: :error, :warning (default), :message.
|
48
49
|
#
|
49
|
-
#
|
50
50
|
# @return [void]
|
51
51
|
def check_gemfile_lock_updated(report_type: :warning)
|
52
52
|
check_manifest_lock_updated(
|
@@ -61,7 +61,6 @@ module Danger
|
|
61
61
|
#
|
62
62
|
# @param report_type [Symbol] (optional) The type of report for the message. Types: :error, :warning (default), :message.
|
63
63
|
#
|
64
|
-
#
|
65
64
|
# @return [void]
|
66
65
|
def check_podfile_lock_updated(report_type: :warning)
|
67
66
|
check_manifest_lock_updated(
|
@@ -76,13 +75,27 @@ module Danger
|
|
76
75
|
#
|
77
76
|
# @param report_type [Symbol] (optional) The type of report for the message. Types: :error, :warning (default), :message.
|
78
77
|
#
|
79
|
-
#
|
80
78
|
# @return [void]
|
81
79
|
def check_swift_package_resolved_updated(report_type: :warning)
|
82
80
|
check_manifest_lock_updated(
|
83
81
|
file_name: 'Package.swift',
|
84
82
|
lock_file_name: 'Package.resolved',
|
85
|
-
instruction:
|
83
|
+
instruction: SWIFT_INSTRUCTION,
|
84
|
+
report_type: report_type
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Check if the `Package.swift` file was modified without a corresponding `Package.resolved` update,
|
89
|
+
# checking for exact path matches
|
90
|
+
#
|
91
|
+
# @param report_type [Symbol] (optional) The type of report for the message. Types: :error, :warning (default), :message.
|
92
|
+
#
|
93
|
+
# @return [void]
|
94
|
+
def check_swift_package_resolved_updated_strict(manifest_path:, manifest_lock_path:, report_type: :warning)
|
95
|
+
check_manifest_lock_updated_strict(
|
96
|
+
manifest_path: manifest_path,
|
97
|
+
manifest_lock_path: manifest_lock_path,
|
98
|
+
instruction: SWIFT_INSTRUCTION,
|
86
99
|
report_type: report_type
|
87
100
|
)
|
88
101
|
end
|
@@ -91,16 +104,27 @@ module Danger
|
|
91
104
|
|
92
105
|
def check_manifest_lock_updated(file_name:, lock_file_name:, instruction:, report_type: :warning)
|
93
106
|
# Find all the modified manifest files
|
94
|
-
manifest_modified_files =
|
107
|
+
manifest_modified_files = git_utils.all_changed_files.select { |f| File.basename(f) == file_name }
|
95
108
|
|
96
109
|
# For each manifest file, check if the corresponding lockfile (in the same dir) was also modified
|
97
110
|
manifest_modified_files.each do |manifest_file|
|
98
|
-
lockfile_modified =
|
111
|
+
lockfile_modified = git_utils.all_changed_files.any? { |f| File.dirname(f) == File.dirname(manifest_file) && File.basename(f) == lock_file_name }
|
99
112
|
next if lockfile_modified
|
100
113
|
|
101
114
|
message = format(MESSAGE, manifest_file, lock_file_name, instruction)
|
102
115
|
reporter.report(message: message, type: report_type)
|
103
116
|
end
|
104
117
|
end
|
118
|
+
|
119
|
+
def check_manifest_lock_updated_strict(manifest_path:, manifest_lock_path:, instruction:, report_type: :warning)
|
120
|
+
manifest_modified = git_utils.all_changed_files.include?(manifest_path)
|
121
|
+
return unless manifest_modified
|
122
|
+
|
123
|
+
lockfile_modified = git_utils.all_changed_files.include?(manifest_lock_path)
|
124
|
+
return if lockfile_modified
|
125
|
+
|
126
|
+
message = format(MESSAGE, manifest_path, File.basename(manifest_lock_path), instruction)
|
127
|
+
reporter.report(message: message, type: report_type)
|
128
|
+
end
|
105
129
|
end
|
106
130
|
end
|
@@ -18,7 +18,7 @@ module Danger
|
|
18
18
|
MEDIA_IN_PR_BODY_PATTERNS = [
|
19
19
|
%r{https?://\S*\.(gif|jpg|jpeg|png|svg)},
|
20
20
|
%r{https?://\S*\.(mp4|avi|mov|mkv)},
|
21
|
-
%r{https?://\S*github\S+/\S+/assets
|
21
|
+
%r{https?://\S*github\S+/\S+/assets/},
|
22
22
|
/!\[(.*?)\]\((.*?)\)/,
|
23
23
|
/<img\s+[^>]*src\s*=\s*[^>]*>/,
|
24
24
|
/<video\s+[^>]*src\s*=\s*[^>]*>/
|
@@ -31,7 +31,7 @@ module Danger
|
|
31
31
|
# displaying a warning if view files have been modified but no screenshot or video is included.
|
32
32
|
#
|
33
33
|
# @return [void]
|
34
|
-
def check
|
34
|
+
def check(report_type: :warning)
|
35
35
|
view_files_modified = git.modified_files.any? do |file|
|
36
36
|
VIEW_EXTENSIONS_IOS =~ file || VIEW_EXTENSIONS_ANDROID =~ file
|
37
37
|
end
|
@@ -40,7 +40,7 @@ module Danger
|
|
40
40
|
github.pr_body =~ pattern
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
reporter.report(message: MESSAGE, type: report_type) if view_files_modified && !pr_has_media
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Parses and updates changelog files for software projects.
|
4
|
+
#
|
5
|
+
# This class provides functionality to parse a changelog file, identify pending
|
6
|
+
# sections for upcoming releases, and update the changelog for new releases based on
|
7
|
+
# semantic versioning conventions.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# parser = ChangelogParser.new(file: 'CHANGELOG.md')
|
11
|
+
# latest_version = parser.parse_pending_section
|
12
|
+
# new_version = parser.guessed_next_semantic_version(current: '1.0.0')
|
13
|
+
# parser.update_for_new_release(new_version: new_version)
|
14
|
+
class ChangelogParser
|
15
|
+
PENDING_SECTION_TITLE = 'Trunk'
|
16
|
+
EMPTY_PLACEHOLDER = '_None_'
|
17
|
+
SUBSECTIONS_SEMVER_MAP = { 'Breaking Changes': 3, 'New Features': 2, 'Bug Fixes': 1, 'Internal Changes': 1 }.freeze
|
18
|
+
|
19
|
+
def initialize(file: 'CHANGELOG.md')
|
20
|
+
@lines = File.readlines(file)
|
21
|
+
@current_index = nil
|
22
|
+
@pending_section = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return the title of the section after the pending one -- which should match the latest released version
|
26
|
+
def parse_pending_section
|
27
|
+
(lines_before_first_section, _, title) = advance_to_next_header(level: 2)
|
28
|
+
raise "Expected #{PENDING_SECTION_TITLE} as first section but found #{title} instead." unless title == PENDING_SECTION_TITLE
|
29
|
+
|
30
|
+
subsections = []
|
31
|
+
prev_subtitle = nil
|
32
|
+
loop do
|
33
|
+
(lines, next_level, next_subtitle) = advance_to_next_header(level: 2..3)
|
34
|
+
subsections.append({ title: prev_subtitle, lines: lines }) unless lines.reject { |l| l.chomp.empty? || l.chomp == EMPTY_PLACEHOLDER }.empty?
|
35
|
+
prev_subtitle = next_subtitle
|
36
|
+
|
37
|
+
break if next_level < 3
|
38
|
+
end
|
39
|
+
@pending_section = { lines_before: lines_before_first_section, subsections: subsections, next_title: prev_subtitle }
|
40
|
+
prev_subtitle
|
41
|
+
end
|
42
|
+
|
43
|
+
def cleaned_pending_changelog_lines
|
44
|
+
lines = []
|
45
|
+
@pending_section[:subsections].map do |s|
|
46
|
+
lines.append "### #{s[:title]}\n" unless s[:title].nil? # subsection title is nil for lines between h2 and first h3
|
47
|
+
lines += s[:lines]
|
48
|
+
end
|
49
|
+
lines
|
50
|
+
end
|
51
|
+
|
52
|
+
def guessed_next_semantic_version(current:)
|
53
|
+
comps = current.split('.')
|
54
|
+
idx_to_bump = 3 - semver_category
|
55
|
+
comps[idx_to_bump] = (comps[idx_to_bump].to_i + 1).to_s
|
56
|
+
((idx_to_bump + 1)...(comps.length)).each { |i| comps[i] = '0' }
|
57
|
+
comps.join('.')
|
58
|
+
end
|
59
|
+
|
60
|
+
def update_for_new_release(new_version:, new_file: 'CHANGELOG.md')
|
61
|
+
raise 'You need to call #parse_pending_section first' if @pending_section.nil?
|
62
|
+
|
63
|
+
File.open(new_file, 'w') do |f|
|
64
|
+
f.puts @pending_section[:lines_before]
|
65
|
+
# Empty placeholder section for next version after this one
|
66
|
+
f.puts placeholder_section
|
67
|
+
# Section for new version, with the non-empty subsections found while parsing first section
|
68
|
+
f.puts "## #{new_version}\n\n"
|
69
|
+
f.puts cleaned_pending_changelog_lines
|
70
|
+
f.puts "## #{@pending_section[:next_title]}"
|
71
|
+
f.puts read_up_to_end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Advance line pointer to next index of provided `level`
|
78
|
+
# @return [Array] A 3-item array of [scanned_lines, next_header_level, next_header_title]
|
79
|
+
def advance_to_next_header(level:)
|
80
|
+
range = level.is_a?(Range) ? level : level..level
|
81
|
+
regex = /^(\#{#{range.min},#{range.max}}) ?([^#].*)$/ # A line starting with {range.min,range.max} times '#' then optional space then a title
|
82
|
+
start_idx = @current_index.nil? ? 0 : @current_index + 1
|
83
|
+
offset = @lines[start_idx...].index { |l| l =~ regex }
|
84
|
+
@current_index = offset.nil? ? -1 : start_idx + offset
|
85
|
+
|
86
|
+
m = regex.match(@lines[@current_index])
|
87
|
+
[@lines[start_idx...@current_index], m[1].length, m[2]]
|
88
|
+
end
|
89
|
+
|
90
|
+
def read_up_to_end
|
91
|
+
idx = @current_index + 1
|
92
|
+
@current_index = -1
|
93
|
+
@lines[idx...]
|
94
|
+
end
|
95
|
+
|
96
|
+
def placeholder_section
|
97
|
+
lines = ["## #{PENDING_SECTION_TITLE}\n\n"]
|
98
|
+
lines += SUBSECTIONS_SEMVER_MAP.keys.map { |s| "### #{s}\n\n#{EMPTY_PLACEHOLDER}\n\n" }
|
99
|
+
lines.join
|
100
|
+
end
|
101
|
+
|
102
|
+
# @return the SemVer category (as described in Gem::Version doc). 3=major, 2=minor, 1=patch
|
103
|
+
def semver_category
|
104
|
+
raise 'You need to call #parse_pending_section first' if @pending_section.nil?
|
105
|
+
|
106
|
+
@pending_section[:subsections].map { |s| SUBSECTIONS_SEMVER_MAP[s[:title].to_sym] || 1 }.max || 1
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Provides methods for colored console output and user interaction.
|
4
|
+
#
|
5
|
+
# The Console module contains methods for printing colored text to the terminal using
|
6
|
+
# ANSI escape codes. It also includes utility methods for prompting user input.
|
7
|
+
module Console
|
8
|
+
# ANSI colors
|
9
|
+
RED = 1
|
10
|
+
GREEN = 2
|
11
|
+
YELLOW = 3
|
12
|
+
PURPLE = 4
|
13
|
+
|
14
|
+
def self.color_puts(lines, color_code:)
|
15
|
+
puts "\x1b[3#{color_code}m#{lines}\x1b[0m"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.header(title)
|
19
|
+
color_puts(">>> #{title}", color_code: GREEN) # green
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.info(text)
|
23
|
+
color_puts(text, color_code: YELLOW) # yellow
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.warning(text)
|
27
|
+
color_puts(text, color_code: RED) # red
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.print_indented_lines(lines)
|
31
|
+
color_puts(lines.map { |l| "| #{l}" }.join, color_code: YELLOW)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.prompt(text, default_value)
|
35
|
+
color_puts("#{text}? [default: #{default_value}] ", color_code: GREEN)
|
36
|
+
answer = $stdin.gets.chomp
|
37
|
+
answer = default_value if answer.empty?
|
38
|
+
answer
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.confirm(text)
|
42
|
+
color_puts("#{text} [y/n]?", color_code: GREEN)
|
43
|
+
answer = $stdin.gets.chomp
|
44
|
+
answer.downcase == 'y'
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
# Helper methods for common Git operations: checking / creating branches, preparing a pull request and
|
6
|
+
# committing / pushing files.
|
7
|
+
module GitHelper
|
8
|
+
def self.current_branch
|
9
|
+
`git --no-pager branch --show-current`.chomp
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.check_or_create_branch(new_version)
|
13
|
+
release_branch = "release/#{new_version}"
|
14
|
+
branch_exists = !`git --no-pager branch -a --list --no-color #{release_branch}`.chomp.empty?
|
15
|
+
if current_branch == release_branch
|
16
|
+
puts 'Already on release branch'
|
17
|
+
elsif branch_exists
|
18
|
+
Rake.sh('git', 'checkout', release_branch)
|
19
|
+
else # create it
|
20
|
+
abort('Aborted, as not run from trunk nor release branch') unless current_branch == 'trunk' || Console.confirm("You are not on 'trunk', nor already on '#{release_branch}'. Do you really want to cut the release branch from #{current_branch}?")
|
21
|
+
|
22
|
+
Rake.sh('git', 'checkout', '-b', release_branch)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.prepare_github_pr(head, base, title, body)
|
27
|
+
require 'open-uri'
|
28
|
+
qtitle = CGI.escape(title)
|
29
|
+
qbody = CGI.escape(body)
|
30
|
+
uri = "https://github.com/Automattic/dangermattic/compare/#{base}...#{head}?expand=1&title=#{qtitle}&body=#{qbody}"
|
31
|
+
Rake.sh('open', uri)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.commit_files(message, files, push: true)
|
35
|
+
Rake.sh('git', 'add', *files)
|
36
|
+
Rake.sh('git', 'commit', '-m', message)
|
37
|
+
Rake.sh('git', 'push', '-q', '-u', 'origin', current_branch) if push
|
38
|
+
end
|
39
|
+
end
|
@@ -17,7 +17,7 @@ module Danger
|
|
17
17
|
describe 'Bundler' do
|
18
18
|
it 'reports a warning when a PR changed the Gemfile but not the Gemfile.lock' do
|
19
19
|
modified_files = ['Gemfile']
|
20
|
-
allow(@plugin.
|
20
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
21
21
|
|
22
22
|
@plugin.check_gemfile_lock_updated
|
23
23
|
|
@@ -27,7 +27,7 @@ module Danger
|
|
27
27
|
|
28
28
|
it 'reports no warnings when both the Gemfile and the Gemfile.lock were updated' do
|
29
29
|
modified_files = ['Gemfile', 'Gemfile.lock']
|
30
|
-
allow(@plugin.
|
30
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
31
31
|
|
32
32
|
@plugin.check_gemfile_lock_updated
|
33
33
|
|
@@ -36,7 +36,7 @@ module Danger
|
|
36
36
|
|
37
37
|
it 'reports no warnings when only the Gemfile.lock was updated' do
|
38
38
|
modified_files = ['Gemfile.lock']
|
39
|
-
allow(@plugin.
|
39
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
40
40
|
|
41
41
|
@plugin.check_gemfile_lock_updated
|
42
42
|
|
@@ -47,7 +47,7 @@ module Danger
|
|
47
47
|
describe 'CocoaPods' do
|
48
48
|
it 'reports a warning when a PR changed the Podfile but not the Podfile.lock' do
|
49
49
|
modified_files = ['Podfile']
|
50
|
-
allow(@plugin.
|
50
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
51
51
|
|
52
52
|
@plugin.check_podfile_lock_updated
|
53
53
|
|
@@ -57,7 +57,7 @@ module Danger
|
|
57
57
|
|
58
58
|
it 'reports no warnings when both the Podfile and the Podfile.lock were updated' do
|
59
59
|
modified_files = ['Podfile', 'Podfile.lock']
|
60
|
-
allow(@plugin.
|
60
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
61
61
|
|
62
62
|
@plugin.check_podfile_lock_updated
|
63
63
|
|
@@ -66,7 +66,7 @@ module Danger
|
|
66
66
|
|
67
67
|
it 'reports a warning when a PR changed a custom located Podfile but not the corresponding Podfile.lock' do
|
68
68
|
modified_files = ['./path/to/Podfile', './my/Podfile.lock']
|
69
|
-
allow(@plugin.
|
69
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
70
70
|
|
71
71
|
@plugin.check_podfile_lock_updated
|
72
72
|
|
@@ -76,7 +76,7 @@ module Danger
|
|
76
76
|
|
77
77
|
it 'reports multiple warnings when a PR changed multiple custom located Podfiles but not the corresponding Podfile.lock' do
|
78
78
|
modified_files = ['./dir1/Podfile', './dir2/Podfile', './dir3/Podfile', './dir1/Podfile.lock']
|
79
|
-
allow(@plugin.
|
79
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
80
80
|
|
81
81
|
@plugin.check_podfile_lock_updated
|
82
82
|
|
@@ -89,7 +89,7 @@ module Danger
|
|
89
89
|
|
90
90
|
it 'reports no warnings when both custom located Podfile`s and their corresponding Podfile.lock were updated' do
|
91
91
|
modified_files = ['./my/path/to/Podfile', './another/path/to/Podfile', './my/path/to/Podfile.lock', './another/path/to/Podfile.lock']
|
92
|
-
allow(@plugin.
|
92
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
93
93
|
|
94
94
|
@plugin.check_podfile_lock_updated
|
95
95
|
|
@@ -98,7 +98,7 @@ module Danger
|
|
98
98
|
|
99
99
|
it 'reports no warnings when only the Podfile.lock was updated' do
|
100
100
|
modified_files = ['Podfile.lock']
|
101
|
-
allow(@plugin.
|
101
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
102
102
|
|
103
103
|
@plugin.check_podfile_lock_updated
|
104
104
|
|
@@ -107,32 +107,73 @@ module Danger
|
|
107
107
|
end
|
108
108
|
|
109
109
|
describe 'Swift Package Manager' do
|
110
|
-
|
111
|
-
|
112
|
-
|
110
|
+
describe '#check_swift_package_resolved_updated' do
|
111
|
+
it 'reports a warning when a PR changed the Package.swift but not the Package.resolved' do
|
112
|
+
modified_files = ['Package.swift']
|
113
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
113
114
|
|
114
|
-
|
115
|
+
@plugin.check_swift_package_resolved_updated
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
|
117
|
+
expected_warning = format(ManifestPRChecker::MESSAGE, 'Package.swift', 'Package.resolved', ManifestPRChecker::SWIFT_INSTRUCTION)
|
118
|
+
expect(@dangerfile).to report_warnings([expected_warning])
|
119
|
+
end
|
119
120
|
|
120
|
-
|
121
|
-
|
122
|
-
|
121
|
+
it 'reports no warnings when both the Package.swift and the Package.resolved were updated' do
|
122
|
+
modified_files = ['Package.swift', 'Package.resolved']
|
123
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
123
124
|
|
124
|
-
|
125
|
+
@plugin.check_swift_package_resolved_updated
|
125
126
|
|
126
|
-
|
127
|
+
expect(@dangerfile).to not_report
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'reports no warnings when only the Package.resolved was updated' do
|
131
|
+
modified_files = ['Package.resolved']
|
132
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
133
|
+
|
134
|
+
@plugin.check_swift_package_resolved_updated
|
135
|
+
|
136
|
+
expect(@dangerfile).to not_report
|
137
|
+
end
|
127
138
|
end
|
128
139
|
|
129
|
-
|
130
|
-
|
131
|
-
|
140
|
+
describe '#check_swift_package_resolved_updated_strict' do
|
141
|
+
it 'reports a warning when a PR changed the specific Package.swift but not its Package.resolved' do
|
142
|
+
modified_files = ['Apps/App1/Package.swift', 'Apps/App2/Package.swift', 'Apps/App2/Package.resolved']
|
143
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
132
144
|
|
133
|
-
|
145
|
+
@plugin.check_swift_package_resolved_updated_strict(
|
146
|
+
manifest_path: 'Apps/App1/Package.swift',
|
147
|
+
manifest_lock_path: 'Apps/App1/Package.resolved'
|
148
|
+
)
|
134
149
|
|
135
|
-
|
150
|
+
expected_warning = format(ManifestPRChecker::MESSAGE, 'Apps/App1/Package.swift', 'Package.resolved', ManifestPRChecker::SWIFT_INSTRUCTION)
|
151
|
+
expect(@dangerfile).to report_warnings([expected_warning])
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'reports no warning when both the specific Package.swift and Package.resolved were updated' do
|
155
|
+
modified_files = ['Apps/App1/Package.swift', 'Apps/App1/Package.resolved']
|
156
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
157
|
+
|
158
|
+
@plugin.check_swift_package_resolved_updated_strict(
|
159
|
+
manifest_path: 'Apps/App1/Package.swift',
|
160
|
+
manifest_lock_path: 'Apps/App1/Package.resolved'
|
161
|
+
)
|
162
|
+
|
163
|
+
expect(@dangerfile).to not_report
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'reports no warning when the specific Package.swift was not modified' do
|
167
|
+
modified_files = ['Apps/App2/Package.swift', 'Apps/App2/Package.resolved']
|
168
|
+
allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
|
169
|
+
|
170
|
+
@plugin.check_swift_package_resolved_updated_strict(
|
171
|
+
manifest_path: 'Apps/App1/Package.swift',
|
172
|
+
manifest_lock_path: 'Apps/App1/Package.resolved'
|
173
|
+
)
|
174
|
+
|
175
|
+
expect(@dangerfile).to not_report
|
176
|
+
end
|
136
177
|
end
|
137
178
|
end
|
138
179
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -28,7 +28,6 @@ require 'danger_plugin'
|
|
28
28
|
# it comes with an extra function `.string` which will
|
29
29
|
# strip all ANSI colours from the string.
|
30
30
|
|
31
|
-
# rubocop:disable Lint/NestedMethodDefinition
|
32
31
|
def testing_ui
|
33
32
|
@output = StringIO.new
|
34
33
|
def @output.winsize
|
@@ -41,7 +40,6 @@ def testing_ui
|
|
41
40
|
end
|
42
41
|
cork
|
43
42
|
end
|
44
|
-
# rubocop:enable Lint/NestedMethodDefinition
|
45
43
|
|
46
44
|
# Example environment (ENV)
|
47
45
|
def testing_env
|
@@ -75,7 +75,7 @@ module Danger
|
|
75
75
|
expect(@dangerfile).to not_report
|
76
76
|
end
|
77
77
|
|
78
|
-
it 'does nothing when a PR with view code changes has a video defined with a simple URL' do
|
78
|
+
it 'does nothing when a PR with view code changes has a video defined with a simple repo assets URL' do
|
79
79
|
allow(@plugin.github).to receive(:pr_body)
|
80
80
|
.and_return("see video:\nhttps://github.com/woocommerce/woocommerce-ios/assets/1864060/0e983305-5047-40a3-8829-734e0b582b96 body body")
|
81
81
|
|
@@ -83,6 +83,15 @@ module Danger
|
|
83
83
|
|
84
84
|
expect(@dangerfile).to not_report
|
85
85
|
end
|
86
|
+
|
87
|
+
it 'does nothing when a PR with view code changes has a video defined with a simple GitHub assets URL' do
|
88
|
+
allow(@plugin.github).to receive(:pr_body)
|
89
|
+
.and_return("see video:\nhttps://github.com/user-attachments/assets/f3461fec-f96c-4376-9e00-f8faf65f3457 body body")
|
90
|
+
|
91
|
+
@plugin.check
|
92
|
+
|
93
|
+
expect(@dangerfile).to not_report
|
94
|
+
end
|
86
95
|
end
|
87
96
|
|
88
97
|
shared_examples 'PR without view code changes' do |modified_files|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danger-dangermattic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Automattic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: danger
|
@@ -201,6 +201,7 @@ files:
|
|
201
201
|
- ".buildkite/gem-push.sh"
|
202
202
|
- ".buildkite/pipeline.yml"
|
203
203
|
- ".bundle/config"
|
204
|
+
- ".github/workflows/README.md"
|
204
205
|
- ".github/workflows/reusable-check-labels-on-issues.yml"
|
205
206
|
- ".github/workflows/reusable-retry-buildkite-step-on-events.yml"
|
206
207
|
- ".github/workflows/reusable-run-danger.yml"
|
@@ -234,6 +235,9 @@ files:
|
|
234
235
|
- lib/dangermattic/plugins/pr_size_checker.rb
|
235
236
|
- lib/dangermattic/plugins/tracks_checker.rb
|
236
237
|
- lib/dangermattic/plugins/view_changes_checker.rb
|
238
|
+
- rakelib/changelog_parser.rake
|
239
|
+
- rakelib/console.rake
|
240
|
+
- rakelib/git_helpers.rake
|
237
241
|
- spec/android_release_checker_spec.rb
|
238
242
|
- spec/android_strings_checker_spec.rb
|
239
243
|
- spec/android_unit_test_checker_spec.rb
|