gh-formatter 0.1.0__tar.gz
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.
- gh_formatter-0.1.0/.gh-formatter.yml +229 -0
- gh_formatter-0.1.0/.github/CODEOWNERS +10 -0
- gh_formatter-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +91 -0
- gh_formatter-0.1.0/.github/ISSUE_TEMPLATE/config.yml +7 -0
- gh_formatter-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +50 -0
- gh_formatter-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +33 -0
- gh_formatter-0.1.0/.github/dependabot.yml +36 -0
- gh_formatter-0.1.0/.github/rulesets/README.md +50 -0
- gh_formatter-0.1.0/.github/workflows/build_and_test.yml +82 -0
- gh_formatter-0.1.0/.github/workflows/release.yml +105 -0
- gh_formatter-0.1.0/.gitignore +218 -0
- gh_formatter-0.1.0/.pre-commit-config.yaml +47 -0
- gh_formatter-0.1.0/.pre-commit-hooks.yaml +8 -0
- gh_formatter-0.1.0/.yamllint.yml +34 -0
- gh_formatter-0.1.0/CODE_OF_CONDUCT.md +60 -0
- gh_formatter-0.1.0/CONTRIBUTING.md +144 -0
- gh_formatter-0.1.0/LICENSE +21 -0
- gh_formatter-0.1.0/PKG-INFO +501 -0
- gh_formatter-0.1.0/README.md +468 -0
- gh_formatter-0.1.0/SECURITY.md +24 -0
- gh_formatter-0.1.0/examples/caller_workflow_example.yml +55 -0
- gh_formatter-0.1.0/examples/codeql.yml +59 -0
- gh_formatter-0.1.0/examples/composite_action/action.yml +57 -0
- gh_formatter-0.1.0/examples/docker-publish.yml +99 -0
- gh_formatter-0.1.0/examples/reusable_workflow_example.yml +72 -0
- gh_formatter-0.1.0/examples/workflow_example.yml +160 -0
- gh_formatter-0.1.0/pyproject.toml +122 -0
- gh_formatter-0.1.0/src/gh_formatter/__init__.py +2 -0
- gh_formatter-0.1.0/src/gh_formatter/casing.py +80 -0
- gh_formatter-0.1.0/src/gh_formatter/cli.py +289 -0
- gh_formatter-0.1.0/src/gh_formatter/comments.py +358 -0
- gh_formatter-0.1.0/src/gh_formatter/config.py +341 -0
- gh_formatter-0.1.0/src/gh_formatter/context.py +89 -0
- gh_formatter-0.1.0/src/gh_formatter/directives.py +110 -0
- gh_formatter-0.1.0/src/gh_formatter/discovery.py +62 -0
- gh_formatter-0.1.0/src/gh_formatter/engine.py +108 -0
- gh_formatter-0.1.0/src/gh_formatter/postprocess.py +184 -0
- gh_formatter-0.1.0/src/gh_formatter/project.py +109 -0
- gh_formatter-0.1.0/src/gh_formatter/references.py +60 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/__init__.py +27 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/alphabetize.py +58 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/base.py +29 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/callers.py +157 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/if_expressions.py +68 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/inputs.py +130 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/jobs.py +84 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/keys.py +137 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/lists.py +73 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/names.py +63 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/quotes.py +51 -0
- gh_formatter-0.1.0/src/gh_formatter/rules/style.py +57 -0
- gh_formatter-0.1.0/src/gh_formatter/utils.py +133 -0
- gh_formatter-0.1.0/src/gh_formatter/yamllint_sync.py +78 -0
- gh_formatter-0.1.0/tests/__init__.py +1 -0
- gh_formatter-0.1.0/tests/test_casing.py +36 -0
- gh_formatter-0.1.0/tests/test_cli.py +105 -0
- gh_formatter-0.1.0/tests/test_config.py +140 -0
- gh_formatter-0.1.0/tests/test_cross_file.py +418 -0
- gh_formatter-0.1.0/tests/test_directives.py +139 -0
- gh_formatter-0.1.0/tests/test_regressions.py +465 -0
- gh_formatter-0.1.0/tests/test_rules.py +357 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Comprehensive Configuration for gh-formatter
|
|
2
|
+
# =============================================
|
|
3
|
+
# This file controls all formatting options for GitHub Actions and Workflows.
|
|
4
|
+
# All settings shown below are optional and use the defaults listed.
|
|
5
|
+
|
|
6
|
+
# INDENTATION SETTINGS
|
|
7
|
+
# ====================
|
|
8
|
+
|
|
9
|
+
# Number of spaces to use for general indentation (default: 2)
|
|
10
|
+
# Recommended values: 2 or 4
|
|
11
|
+
indent: 2
|
|
12
|
+
|
|
13
|
+
# Number of spaces to indent sequence (list) item content (default: 4)
|
|
14
|
+
# Must be greater than sequence_offset.
|
|
15
|
+
sequence_indent: 4
|
|
16
|
+
|
|
17
|
+
# Indentation of the dash in sequence items (default: 2)
|
|
18
|
+
# Controls how far the `-` is indented relative to its parent key.
|
|
19
|
+
# Example with sequence_offset: 2 (default), sequence_indent: 4:
|
|
20
|
+
# steps:
|
|
21
|
+
# - name: item1
|
|
22
|
+
# - name: item2
|
|
23
|
+
# Example with sequence_offset: 0, sequence_indent: 2:
|
|
24
|
+
# steps:
|
|
25
|
+
# - name: item1
|
|
26
|
+
# - name: item2
|
|
27
|
+
sequence_offset: 2
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# NAMING CONVENTIONS
|
|
31
|
+
# ==================
|
|
32
|
+
|
|
33
|
+
# Casing convention for input names in actions and workflows
|
|
34
|
+
# Options: "dash-case" or "snake_case"
|
|
35
|
+
# Examples:
|
|
36
|
+
# dash-case: my-input, debug-mode, run-tests
|
|
37
|
+
# snake_case: my_input, debug_mode, run_tests
|
|
38
|
+
# Default: "dash-case"
|
|
39
|
+
input_casing: "dash-case"
|
|
40
|
+
|
|
41
|
+
# Casing convention for job names in workflows
|
|
42
|
+
# Options: "snake_case" or "dash-case"
|
|
43
|
+
# Examples:
|
|
44
|
+
# snake_case: build_job, run_tests, deploy_app
|
|
45
|
+
# dash-case: build-job, run-tests, deploy-app
|
|
46
|
+
# Default: "snake_case"
|
|
47
|
+
job_casing: "snake_case"
|
|
48
|
+
|
|
49
|
+
# How to treat env-var style names (SERVER_IMAGE, MM_ENV) when renaming
|
|
50
|
+
# inputs and jobs:
|
|
51
|
+
# false (default): renamed to the configured casing like any other name
|
|
52
|
+
# true: kept uppercase, separators normalized to underscores
|
|
53
|
+
# (SERVER-IMAGE becomes SERVER_IMAGE)
|
|
54
|
+
preserve_uppercase_names: false
|
|
55
|
+
|
|
56
|
+
# Line endings for formatted files
|
|
57
|
+
# Options: "preserve" (keep each file's existing endings) or "lf" (Unix)
|
|
58
|
+
# Default: "preserve"
|
|
59
|
+
line_endings: "preserve"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# QUOTE STYLE
|
|
63
|
+
# ===========
|
|
64
|
+
|
|
65
|
+
# Quote character to enforce on already-quoted scalars.
|
|
66
|
+
# Options: "double", "single", or "preserve"
|
|
67
|
+
# double: normalize every quoted scalar to "..." (default)
|
|
68
|
+
# single: normalize every quoted scalar to '...'
|
|
69
|
+
# preserve: leave each scalar's existing quoting untouched
|
|
70
|
+
# Plain (unquoted) values are never force-quoted, and ruamel falls back
|
|
71
|
+
# to double quoting when a value cannot be single-quoted safely.
|
|
72
|
+
quote_style: "double"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# YAMLLINT INTEROP
|
|
76
|
+
# ================
|
|
77
|
+
|
|
78
|
+
# Make a yamllint config the source of truth for indentation so a format
|
|
79
|
+
# never produces output yamllint would reject. Requires yamllint installed.
|
|
80
|
+
# Options:
|
|
81
|
+
# false (default): ignore yamllint, use the indentation settings above
|
|
82
|
+
# true: discover .yamllint(.yml/.yaml) in the working directory
|
|
83
|
+
# <path>: read indentation from that explicit yamllint config
|
|
84
|
+
# When enabled, the derived indent/sequence settings override the ones above.
|
|
85
|
+
defer_to_yamllint: false
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# CALLER INPUTS
|
|
89
|
+
# =============
|
|
90
|
+
|
|
91
|
+
# How to handle a caller's with: keys that don't match a LOCAL reusable
|
|
92
|
+
# workflow/action's declared inputs (uses: ./...). Marketplace actions are
|
|
93
|
+
# never checked.
|
|
94
|
+
# Options:
|
|
95
|
+
# "error" (default): report the mismatch as an error and fail the run
|
|
96
|
+
# "fix": rename the caller's keys to match (at your own risk)
|
|
97
|
+
# "ignore": leave caller inputs alone
|
|
98
|
+
caller_inputs: "error"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# ALPHABETICAL SORTING
|
|
102
|
+
# ====================
|
|
103
|
+
|
|
104
|
+
# Mapping blocks whose entries are sorted alphabetically (case-insensitive).
|
|
105
|
+
# Entry order in these blocks never carries meaning, so sorting them makes
|
|
106
|
+
# diffs and reviews predictable. Set to [] to disable sorting entirely, or
|
|
107
|
+
# add further block names (e.g. "permissions").
|
|
108
|
+
alphabetize:
|
|
109
|
+
- env
|
|
110
|
+
- inputs
|
|
111
|
+
- outputs
|
|
112
|
+
- secrets
|
|
113
|
+
- with
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# LIST FORMATTING STYLE
|
|
117
|
+
# =====================
|
|
118
|
+
|
|
119
|
+
# How to format trigger filter lists under `on:` (branches, tags, paths, ...)
|
|
120
|
+
# Options: "flow" or "block"
|
|
121
|
+
# flow: [item1, item2, item3]
|
|
122
|
+
# block: - item1
|
|
123
|
+
# - item2
|
|
124
|
+
# - item3
|
|
125
|
+
# Default: "block"
|
|
126
|
+
list_style: "block"
|
|
127
|
+
|
|
128
|
+
# Which keys under `on:` are treated as filter lists. Single string values
|
|
129
|
+
# are promoted to lists and the configured list_style is applied.
|
|
130
|
+
# Default shown below.
|
|
131
|
+
list_keys:
|
|
132
|
+
- branches
|
|
133
|
+
- branches-ignore
|
|
134
|
+
- tags
|
|
135
|
+
- tags-ignore
|
|
136
|
+
- paths
|
|
137
|
+
- paths-ignore
|
|
138
|
+
- types
|
|
139
|
+
- workflows
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# BLANK LINES
|
|
143
|
+
# ===========
|
|
144
|
+
|
|
145
|
+
# Insert a blank line between consecutive steps (default: true)
|
|
146
|
+
blank_line_between_steps: true
|
|
147
|
+
|
|
148
|
+
# Insert a blank line between job definitions (default: true)
|
|
149
|
+
blank_line_between_jobs: true
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# RULE TOGGLES
|
|
153
|
+
# ============
|
|
154
|
+
|
|
155
|
+
# Disable individual rules or post-processors by id.
|
|
156
|
+
# Run `gh-formatter --list-rules` to see all available ids.
|
|
157
|
+
# All rules are enabled by default.
|
|
158
|
+
rules: {}
|
|
159
|
+
# Example:
|
|
160
|
+
# rules:
|
|
161
|
+
# capitalize-names: false
|
|
162
|
+
# blank-lines: false
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# KEY ORDERING
|
|
166
|
+
# ============
|
|
167
|
+
|
|
168
|
+
# Order of keys for GitHub Actions workflow files (.github/workflows/*.yml)
|
|
169
|
+
# Keys not listed here will be placed at the end in alphabetical order
|
|
170
|
+
# Default order shown below (recommended for readability)
|
|
171
|
+
key_order_workflow:
|
|
172
|
+
- name
|
|
173
|
+
- run-name
|
|
174
|
+
- "on" # quoted so YAML 1.1 linters don't read it as the boolean true
|
|
175
|
+
- concurrency
|
|
176
|
+
- permissions
|
|
177
|
+
- env
|
|
178
|
+
- defaults
|
|
179
|
+
- jobs
|
|
180
|
+
|
|
181
|
+
# Order of keys for GitHub Actions definition files (action.yml / action.yaml)
|
|
182
|
+
# Keys not listed here will be placed at the end in alphabetical order
|
|
183
|
+
# Default order shown below (recommended for readability)
|
|
184
|
+
key_order_action:
|
|
185
|
+
- name
|
|
186
|
+
- description
|
|
187
|
+
- author
|
|
188
|
+
- inputs
|
|
189
|
+
- outputs
|
|
190
|
+
- runs
|
|
191
|
+
- branding
|
|
192
|
+
|
|
193
|
+
# Order of keys inside each job definition
|
|
194
|
+
# Default order shown below
|
|
195
|
+
key_order_job:
|
|
196
|
+
- name
|
|
197
|
+
- if
|
|
198
|
+
- needs
|
|
199
|
+
- runs-on
|
|
200
|
+
- env
|
|
201
|
+
- uses
|
|
202
|
+
- with
|
|
203
|
+
- secrets
|
|
204
|
+
- permissions
|
|
205
|
+
- environment
|
|
206
|
+
- concurrency
|
|
207
|
+
- strategy
|
|
208
|
+
- container
|
|
209
|
+
- services
|
|
210
|
+
- outputs
|
|
211
|
+
- defaults
|
|
212
|
+
- timeout-minutes
|
|
213
|
+
- continue-on-error
|
|
214
|
+
- steps
|
|
215
|
+
|
|
216
|
+
# Order of keys inside each step
|
|
217
|
+
# Default order shown below
|
|
218
|
+
key_order_step:
|
|
219
|
+
- name
|
|
220
|
+
- id
|
|
221
|
+
- if
|
|
222
|
+
- env
|
|
223
|
+
- uses
|
|
224
|
+
- continue-on-error
|
|
225
|
+
- run
|
|
226
|
+
- with
|
|
227
|
+
- working-directory
|
|
228
|
+
- shell
|
|
229
|
+
- timeout-minutes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Code owners for gh-formatter
|
|
2
|
+
#
|
|
3
|
+
# The owner(s) listed here are automatically requested for review on every PR
|
|
4
|
+
# and — combined with the "Require review from Code Owners" branch ruleset —
|
|
5
|
+
# are the ONLY accounts whose approval can satisfy the required review.
|
|
6
|
+
#
|
|
7
|
+
# Keep this list to the repository admin(s) only. Anyone added here who also
|
|
8
|
+
# has Write access can approve & merge, so do not add external contributors.
|
|
9
|
+
|
|
10
|
+
* @nimpsch
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report incorrect or unexpected formatting behavior
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to report a bug! A minimal reproduction
|
|
10
|
+
makes fixing it dramatically faster.
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: what-happened
|
|
14
|
+
attributes:
|
|
15
|
+
label: What happened?
|
|
16
|
+
description: A clear description of the bug.
|
|
17
|
+
placeholder: gh-formatter changed X into Y, but it should have ...
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: input-yaml
|
|
23
|
+
attributes:
|
|
24
|
+
label: Input YAML
|
|
25
|
+
description: >
|
|
26
|
+
The smallest workflow/action snippet that reproduces the problem.
|
|
27
|
+
This will be rendered as YAML, no backticks needed.
|
|
28
|
+
render: yaml
|
|
29
|
+
placeholder: |
|
|
30
|
+
name: ci
|
|
31
|
+
on: push
|
|
32
|
+
jobs:
|
|
33
|
+
build:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: textarea
|
|
39
|
+
id: command
|
|
40
|
+
attributes:
|
|
41
|
+
label: Command
|
|
42
|
+
description: The exact command you ran.
|
|
43
|
+
render: shell
|
|
44
|
+
placeholder: gh-formatter .github/workflows/ci.yml
|
|
45
|
+
validations:
|
|
46
|
+
required: true
|
|
47
|
+
|
|
48
|
+
- type: textarea
|
|
49
|
+
id: expected
|
|
50
|
+
attributes:
|
|
51
|
+
label: Expected output
|
|
52
|
+
description: What you expected gh-formatter to produce.
|
|
53
|
+
render: yaml
|
|
54
|
+
validations:
|
|
55
|
+
required: true
|
|
56
|
+
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: actual
|
|
59
|
+
attributes:
|
|
60
|
+
label: Actual output
|
|
61
|
+
description: What gh-formatter actually produced.
|
|
62
|
+
render: yaml
|
|
63
|
+
validations:
|
|
64
|
+
required: true
|
|
65
|
+
|
|
66
|
+
- type: textarea
|
|
67
|
+
id: config
|
|
68
|
+
attributes:
|
|
69
|
+
label: Configuration
|
|
70
|
+
description: >
|
|
71
|
+
Your `.gh-formatter.yml` / `[tool.gh-formatter]` config, if any.
|
|
72
|
+
render: yaml
|
|
73
|
+
validations:
|
|
74
|
+
required: false
|
|
75
|
+
|
|
76
|
+
- type: input
|
|
77
|
+
id: version
|
|
78
|
+
attributes:
|
|
79
|
+
label: gh-formatter version
|
|
80
|
+
description: Output of `pip show gh-formatter` (the Version line).
|
|
81
|
+
placeholder: 0.1.0
|
|
82
|
+
validations:
|
|
83
|
+
required: true
|
|
84
|
+
|
|
85
|
+
- type: input
|
|
86
|
+
id: python-version
|
|
87
|
+
attributes:
|
|
88
|
+
label: Python version
|
|
89
|
+
placeholder: "3.12"
|
|
90
|
+
validations:
|
|
91
|
+
required: true
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new rule, option, or improvement
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for suggesting an improvement! Please describe the problem you
|
|
10
|
+
are trying to solve, not only the solution you have in mind.
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: problem
|
|
14
|
+
attributes:
|
|
15
|
+
label: Problem / motivation
|
|
16
|
+
description: What are you trying to achieve? What is painful today?
|
|
17
|
+
placeholder: >
|
|
18
|
+
When formatting reusable workflows, I want ... because ...
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: proposal
|
|
24
|
+
attributes:
|
|
25
|
+
label: Proposed solution
|
|
26
|
+
description: >
|
|
27
|
+
How might this work? If it is a new formatting rule or option,
|
|
28
|
+
show a before/after example.
|
|
29
|
+
render: yaml
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
|
|
33
|
+
- type: textarea
|
|
34
|
+
id: alternatives
|
|
35
|
+
attributes:
|
|
36
|
+
label: Alternatives considered
|
|
37
|
+
description: Other approaches you thought about, and why you ruled them out.
|
|
38
|
+
validations:
|
|
39
|
+
required: false
|
|
40
|
+
|
|
41
|
+
- type: dropdown
|
|
42
|
+
id: contribute
|
|
43
|
+
attributes:
|
|
44
|
+
label: Would you be willing to contribute this?
|
|
45
|
+
options:
|
|
46
|
+
- "Yes, I'd like to open a PR"
|
|
47
|
+
- "Maybe, with some guidance"
|
|
48
|
+
- "No, just suggesting"
|
|
49
|
+
validations:
|
|
50
|
+
required: false
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Thanks for contributing! Please keep PRs focused on one logical change.
|
|
3
|
+
The title becomes the squashed commit subject — make it descriptive and
|
|
4
|
+
write it in the imperative ("Add ...", "Fix ...").
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
## What does this PR do?
|
|
8
|
+
|
|
9
|
+
<!-- A short description of the change. -->
|
|
10
|
+
|
|
11
|
+
## Why?
|
|
12
|
+
|
|
13
|
+
<!-- The motivation / the problem this solves. Link the issue if there is one. -->
|
|
14
|
+
|
|
15
|
+
Fixes #
|
|
16
|
+
|
|
17
|
+
## How was it tested?
|
|
18
|
+
|
|
19
|
+
<!--
|
|
20
|
+
Describe the tests you added and/or the manual verification you did.
|
|
21
|
+
For formatting changes, a before/after YAML example is very helpful.
|
|
22
|
+
-->
|
|
23
|
+
|
|
24
|
+
## Checklist
|
|
25
|
+
|
|
26
|
+
<!--
|
|
27
|
+
No need to tick off formatting, linting, type-checking, or test runs:
|
|
28
|
+
CI runs black, ruff, mypy, pytest, and yamllint (via pre-commit) on every PR.
|
|
29
|
+
-->
|
|
30
|
+
|
|
31
|
+
- [ ] Tests added or updated (bug fixes include a regression test)
|
|
32
|
+
- [ ] Docs updated (README / `.gh-formatter.yml`) if behavior or options changed
|
|
33
|
+
- [ ] This PR is one focused change
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Python packages declared in pyproject.toml.
|
|
4
|
+
- package-ecosystem: pip
|
|
5
|
+
directory: /
|
|
6
|
+
schedule:
|
|
7
|
+
interval: weekly
|
|
8
|
+
# Bump the declared requirement itself (not just a lockfile) so update
|
|
9
|
+
# PRs are still raised for ">=" requirements. Note: for a package that
|
|
10
|
+
# is published to PyPI, Dependabot treats it as a library and may leave
|
|
11
|
+
# an unbounded ">=" requirement alone when the newest release already
|
|
12
|
+
# satisfies it -- add an upper bound (e.g. ">=1,<2") if you want those.
|
|
13
|
+
versioning-strategy: increase
|
|
14
|
+
groups:
|
|
15
|
+
python-dependencies:
|
|
16
|
+
patterns:
|
|
17
|
+
- "*"
|
|
18
|
+
|
|
19
|
+
- package-ecosystem: github-actions
|
|
20
|
+
directory: /
|
|
21
|
+
schedule:
|
|
22
|
+
interval: weekly
|
|
23
|
+
groups:
|
|
24
|
+
github-actions:
|
|
25
|
+
patterns:
|
|
26
|
+
- "*"
|
|
27
|
+
|
|
28
|
+
# Bumps the `rev:` of each hook in .pre-commit-config.yaml.
|
|
29
|
+
- package-ecosystem: pre-commit
|
|
30
|
+
directory: /
|
|
31
|
+
schedule:
|
|
32
|
+
interval: weekly
|
|
33
|
+
groups:
|
|
34
|
+
pre-commit:
|
|
35
|
+
patterns:
|
|
36
|
+
- "*"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Repository rulesets
|
|
2
|
+
|
|
3
|
+
These JSON files are importable [repository rulesets](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository).
|
|
4
|
+
They are kept in the repo for version control; GitHub does **not** apply them
|
|
5
|
+
automatically — you must import them once (and re-import after edits).
|
|
6
|
+
|
|
7
|
+
## How to import
|
|
8
|
+
|
|
9
|
+
1. Go to **Settings → Rules → Rulesets** in the repository.
|
|
10
|
+
2. Click **New ruleset → Import a ruleset**.
|
|
11
|
+
3. Select the JSON file and click **Create**.
|
|
12
|
+
4. Repeat for each file.
|
|
13
|
+
|
|
14
|
+
## Files
|
|
15
|
+
|
|
16
|
+
| File | What it does |
|
|
17
|
+
| ---- | ------------ |
|
|
18
|
+
| `main-branch-protection.json` | Protects the default branch: requires a PR with 1 Code Owner approval, passing CI, linear history, blocks force-push and deletion. |
|
|
19
|
+
| `branch-naming.json` | Enforces a naming convention on all non-default branches pushed to this repo. |
|
|
20
|
+
|
|
21
|
+
## Who can approve & merge
|
|
22
|
+
|
|
23
|
+
- **Approve:** Only accounts in [`.github/CODEOWNERS`](../CODEOWNERS) that also have
|
|
24
|
+
Write+ access satisfy the required review. Today that is only `@nimpsch`.
|
|
25
|
+
External contributors fork the repo and have read-only access, so their reviews
|
|
26
|
+
are non-binding.
|
|
27
|
+
- **Merge:** Only accounts with Write+ access can click merge. On a public repo,
|
|
28
|
+
forkers never have write, so they can never merge. Keep yourself the sole
|
|
29
|
+
admin/collaborator and you remain the only person who can merge.
|
|
30
|
+
|
|
31
|
+
The default-branch ruleset lists **Repository admin (`actor_id: 5`)** as a bypass
|
|
32
|
+
actor so you can merge your own PRs (a PR author cannot approve their own PR).
|
|
33
|
+
Remove the `bypass_actors` entry if you want the review requirement to apply to
|
|
34
|
+
you as well.
|
|
35
|
+
|
|
36
|
+
## Branch naming convention
|
|
37
|
+
|
|
38
|
+
Non-default branches must match:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
^(feature|fix|hotfix|chore|docs|refactor|test|ci|build|perf|release|dependabot)/[a-z0-9._/-]+$
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Examples that pass: `feature/yaml-anchors`, `fix/issue-42`, `docs/readme-badges`,
|
|
45
|
+
`dependabot/pip/black-25.1.0`.
|
|
46
|
+
|
|
47
|
+
> **Note:** Branch-name rules apply only to branches created in *this* repo.
|
|
48
|
+
> A fork is a separate repository, so this rule cannot constrain the head-branch
|
|
49
|
+
> name of a PR opened from someone else's fork — it governs your own branches and
|
|
50
|
+
> any direct collaborators.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: Build and Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Test on Python ${{ matrix.python-version }}
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version:
|
|
20
|
+
- "3.11"
|
|
21
|
+
- "3.12"
|
|
22
|
+
- "3.13"
|
|
23
|
+
- "3.14"
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout code
|
|
27
|
+
uses: actions/checkout@v6
|
|
28
|
+
|
|
29
|
+
- name: Set up Python
|
|
30
|
+
uses: actions/setup-python@v6
|
|
31
|
+
with:
|
|
32
|
+
python-version: ${{ matrix.python-version }}
|
|
33
|
+
|
|
34
|
+
- name: Install package with dev dependencies
|
|
35
|
+
run: |
|
|
36
|
+
python -m pip install --upgrade pip
|
|
37
|
+
pip install -e ".[dev]"
|
|
38
|
+
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: pytest
|
|
41
|
+
|
|
42
|
+
lint:
|
|
43
|
+
name: Lint and type-check
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- name: Checkout code
|
|
47
|
+
uses: actions/checkout@v6
|
|
48
|
+
|
|
49
|
+
- name: Set up Python
|
|
50
|
+
uses: actions/setup-python@v6
|
|
51
|
+
with:
|
|
52
|
+
python-version: "3.12"
|
|
53
|
+
|
|
54
|
+
# gh-formatter must be importable for its (system) pre-commit hook;
|
|
55
|
+
# pre-commit manages the envs for black, ruff, mypy, and yamllint.
|
|
56
|
+
- name: Install package and pre-commit
|
|
57
|
+
run: |
|
|
58
|
+
python -m pip install --upgrade pip
|
|
59
|
+
pip install -e ".[dev]" pre-commit
|
|
60
|
+
|
|
61
|
+
# Single entry point: black, ruff, mypy, the gh-formatter self-check,
|
|
62
|
+
# and yamllint all run through pre-commit (see .pre-commit-config.yaml).
|
|
63
|
+
- name: Run pre-commit
|
|
64
|
+
run: pre-commit run --all-files --show-diff-on-failure
|
|
65
|
+
|
|
66
|
+
build:
|
|
67
|
+
name: Verify package builds
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
steps:
|
|
70
|
+
- name: Checkout code
|
|
71
|
+
uses: actions/checkout@v6
|
|
72
|
+
|
|
73
|
+
- name: Set up Python
|
|
74
|
+
uses: actions/setup-python@v6
|
|
75
|
+
with:
|
|
76
|
+
python-version: "3.12"
|
|
77
|
+
|
|
78
|
+
- name: Build sdist and wheel
|
|
79
|
+
run: |
|
|
80
|
+
python -m pip install --upgrade pip build twine
|
|
81
|
+
python -m build
|
|
82
|
+
twine check dist/*
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
name: Run linting and tests
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout code
|
|
14
|
+
uses: actions/checkout@v6
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v6
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install package with dev dependencies
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Check formatting
|
|
27
|
+
run: gh-formatter --check .
|
|
28
|
+
|
|
29
|
+
- name: Run tests
|
|
30
|
+
run: pytest
|
|
31
|
+
|
|
32
|
+
build:
|
|
33
|
+
name: Build distribution
|
|
34
|
+
needs: test
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout code
|
|
38
|
+
uses: actions/checkout@v6
|
|
39
|
+
|
|
40
|
+
- name: Set up Python
|
|
41
|
+
uses: actions/setup-python@v6
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.12"
|
|
44
|
+
|
|
45
|
+
- name: Verify tag matches package version
|
|
46
|
+
run: |
|
|
47
|
+
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
48
|
+
PKG_VERSION="$(python -c "import re, pathlib; print(re.search(r'__version__ = \"(.+?)\"', pathlib.Path('src/gh_formatter/__init__.py').read_text()).group(1))")"
|
|
49
|
+
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
|
50
|
+
echo "Tag version ($TAG_VERSION) does not match package version ($PKG_VERSION)" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
- name: Install build tooling
|
|
55
|
+
run: python -m pip install --upgrade pip build twine
|
|
56
|
+
|
|
57
|
+
- name: Build sdist and wheel
|
|
58
|
+
run: python -m build
|
|
59
|
+
|
|
60
|
+
- name: Check distribution metadata
|
|
61
|
+
run: twine check dist/*
|
|
62
|
+
|
|
63
|
+
- name: Upload distribution artifacts
|
|
64
|
+
uses: actions/upload-artifact@v7
|
|
65
|
+
with:
|
|
66
|
+
name: dist
|
|
67
|
+
path: dist/
|
|
68
|
+
|
|
69
|
+
publish:
|
|
70
|
+
name: Publish to PyPI
|
|
71
|
+
needs: build
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
permissions: # Required for PyPI Trusted Publishing (OIDC)
|
|
74
|
+
id-token: write
|
|
75
|
+
environment:
|
|
76
|
+
name: pypi
|
|
77
|
+
url: https://pypi.org/p/gh-formatter
|
|
78
|
+
steps:
|
|
79
|
+
- name: Download distribution artifacts
|
|
80
|
+
uses: actions/download-artifact@v8
|
|
81
|
+
with:
|
|
82
|
+
name: dist
|
|
83
|
+
path: dist/
|
|
84
|
+
|
|
85
|
+
- name: Publish to PyPI
|
|
86
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
87
|
+
|
|
88
|
+
github_release:
|
|
89
|
+
name: Create GitHub release
|
|
90
|
+
needs: publish
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
permissions:
|
|
93
|
+
contents: write
|
|
94
|
+
steps:
|
|
95
|
+
- name: Download distribution artifacts
|
|
96
|
+
uses: actions/download-artifact@v8
|
|
97
|
+
with:
|
|
98
|
+
name: dist
|
|
99
|
+
path: dist/
|
|
100
|
+
|
|
101
|
+
- name: Create release with artifacts
|
|
102
|
+
uses: softprops/action-gh-release@v3
|
|
103
|
+
with:
|
|
104
|
+
files: dist/*
|
|
105
|
+
generate_release_notes: true
|