minidb-sql 1.3.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.
Files changed (62) hide show
  1. minidb_sql-1.3.0/.github/PULL_REQUEST_TEMPLATE.md +13 -0
  2. minidb_sql-1.3.0/.github/actionlint.yaml +3 -0
  3. minidb_sql-1.3.0/.github/actions/setup-python/action.yml +15 -0
  4. minidb_sql-1.3.0/.github/dependabot.yml +28 -0
  5. minidb_sql-1.3.0/.github/workflows/apply-release-notes.yml +44 -0
  6. minidb_sql-1.3.0/.github/workflows/auto-approve.yml +52 -0
  7. minidb_sql-1.3.0/.github/workflows/ci.yml +278 -0
  8. minidb_sql-1.3.0/.github/workflows/dco.yml +36 -0
  9. minidb_sql-1.3.0/.github/workflows/dependabot-auto-merge.yml +90 -0
  10. minidb_sql-1.3.0/.github/workflows/links.yml +139 -0
  11. minidb_sql-1.3.0/.github/workflows/pr-title.yml +48 -0
  12. minidb_sql-1.3.0/.github/workflows/release.yml +95 -0
  13. minidb_sql-1.3.0/.github/workflows/scorecard.yml +107 -0
  14. minidb_sql-1.3.0/.github/workflows/security.yml +254 -0
  15. minidb_sql-1.3.0/.github/zizmor.yml +16 -0
  16. minidb_sql-1.3.0/.gitignore +23 -0
  17. minidb_sql-1.3.0/.release-please-manifest.json +3 -0
  18. minidb_sql-1.3.0/AGENTS.md +20 -0
  19. minidb_sql-1.3.0/CHANGELOG.md +91 -0
  20. minidb_sql-1.3.0/CONTRIBUTING.md +86 -0
  21. minidb_sql-1.3.0/LICENSE +21 -0
  22. minidb_sql-1.3.0/PKG-INFO +379 -0
  23. minidb_sql-1.3.0/README.md +355 -0
  24. minidb_sql-1.3.0/SECURITY.md +19 -0
  25. minidb_sql-1.3.0/lychee.toml +17 -0
  26. minidb_sql-1.3.0/main.py +290 -0
  27. minidb_sql-1.3.0/minidb_sql/__init__.py +168 -0
  28. minidb_sql-1.3.0/minidb_sql/column.py +170 -0
  29. minidb_sql-1.3.0/minidb_sql/database.py +258 -0
  30. minidb_sql-1.3.0/minidb_sql/errors.py +176 -0
  31. minidb_sql-1.3.0/minidb_sql/index.py +222 -0
  32. minidb_sql-1.3.0/minidb_sql/parser.py +1278 -0
  33. minidb_sql-1.3.0/minidb_sql/persistence.py +72 -0
  34. minidb_sql-1.3.0/minidb_sql/planner.py +167 -0
  35. minidb_sql-1.3.0/minidb_sql/query.py +1077 -0
  36. minidb_sql-1.3.0/minidb_sql/table.py +274 -0
  37. minidb_sql-1.3.0/minidb_sql/types.py +189 -0
  38. minidb_sql-1.3.0/minidb_sql.egg-info/PKG-INFO +379 -0
  39. minidb_sql-1.3.0/minidb_sql.egg-info/SOURCES.txt +60 -0
  40. minidb_sql-1.3.0/minidb_sql.egg-info/dependency_links.txt +1 -0
  41. minidb_sql-1.3.0/minidb_sql.egg-info/top_level.txt +1 -0
  42. minidb_sql-1.3.0/pyproject.toml +108 -0
  43. minidb_sql-1.3.0/release-please-config.json +17 -0
  44. minidb_sql-1.3.0/scripts/apply-release-notes.sh +107 -0
  45. minidb_sql-1.3.0/scripts/check-dco.sh +43 -0
  46. minidb_sql-1.3.0/scripts/report-scheduled-failure.py +500 -0
  47. minidb_sql-1.3.0/scripts/test_apply_release_notes.py +270 -0
  48. minidb_sql-1.3.0/scripts/test_check_dco.py +127 -0
  49. minidb_sql-1.3.0/scripts/test_release_please.py +44 -0
  50. minidb_sql-1.3.0/scripts/test_report_scheduled_failure.py +223 -0
  51. minidb_sql-1.3.0/scripts/test_workflow_triggers.py +122 -0
  52. minidb_sql-1.3.0/setup.cfg +4 -0
  53. minidb_sql-1.3.0/tests/__init__.py +1 -0
  54. minidb_sql-1.3.0/tests/test_aggregations.py +288 -0
  55. minidb_sql-1.3.0/tests/test_changelog.py +30 -0
  56. minidb_sql-1.3.0/tests/test_crud.py +276 -0
  57. minidb_sql-1.3.0/tests/test_database.py +448 -0
  58. minidb_sql-1.3.0/tests/test_index.py +285 -0
  59. minidb_sql-1.3.0/tests/test_joins.py +407 -0
  60. minidb_sql-1.3.0/tests/test_performance.py +229 -0
  61. minidb_sql-1.3.0/tests/test_persistence.py +376 -0
  62. minidb_sql-1.3.0/tests/test_queries.py +1010 -0
@@ -0,0 +1,13 @@
1
+ ## Summary
2
+
3
+ Describe the change in a few sentences.
4
+
5
+ ## Verification
6
+
7
+ List the checks you ran.
8
+
9
+ ## Checklist
10
+
11
+ - [ ] All commits in this pull request are signed off with `git commit -s`
12
+ - [ ] PR title uses one Conventional Commits prefix (`feat`/`fix`/`docs`/`style`/`refactor`/`perf`/`test`/`build`/`ci`/`chore`/`revert`)
13
+ - [ ] I ran the relevant test, lint, and format steps for the files I changed
@@ -0,0 +1,3 @@
1
+ # GitHub-hosted runners only. Custom labels belong here if that changes.
2
+ self-hosted-runner:
3
+ labels: []
@@ -0,0 +1,15 @@
1
+ name: Setup Python
2
+ description: Install the Python version used by CI and release jobs.
3
+
4
+ inputs:
5
+ python-version:
6
+ description: CPython version to install
7
+ required: true
8
+
9
+ runs:
10
+ using: composite
11
+ steps:
12
+ - name: Setup Python
13
+ uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7
14
+ with:
15
+ python-version: ${{ inputs.python-version }}
@@ -0,0 +1,28 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ rebase-strategy: "auto"
8
+ open-pull-requests-limit: 5
9
+ groups:
10
+ actions:
11
+ patterns:
12
+ - "*"
13
+ update-types:
14
+ - "minor"
15
+ - "patch"
16
+ - package-ecosystem: "pip"
17
+ directory: "/"
18
+ schedule:
19
+ interval: "weekly"
20
+ rebase-strategy: "auto"
21
+ open-pull-requests-limit: 5
22
+ groups:
23
+ python:
24
+ patterns:
25
+ - "*"
26
+ update-types:
27
+ - "minor"
28
+ - "patch"
@@ -0,0 +1,44 @@
1
+ # Cheap apply of curated notes onto a GitHub Release.
2
+ # Reads branch release-note-<semver> or vars RELEASE_NOTES +
3
+ # RELEASE_NOTES_TAG. Deletes the notes branch after a successful
4
+ # apply. Does not compile the package.
5
+ name: Apply release notes
6
+
7
+ on:
8
+ workflow_dispatch:
9
+ inputs:
10
+ tag:
11
+ description: "Release tag (e.g. v1.2.0)"
12
+ required: true
13
+ type: string
14
+
15
+ concurrency:
16
+ group: apply-release-notes-${{ inputs.tag }}
17
+ cancel-in-progress: false
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ jobs:
23
+ apply:
24
+ name: Apply notes
25
+ runs-on: ubuntu-latest
26
+ timeout-minutes: 5
27
+ permissions:
28
+ contents: write
29
+ env:
30
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31
+ GH_REPO: ${{ github.repository }}
32
+ TAG: ${{ inputs.tag }}
33
+ RELEASE_NOTES: ${{ vars.RELEASE_NOTES }}
34
+ RELEASE_NOTES_TAG: ${{ vars.RELEASE_NOTES_TAG }}
35
+ steps:
36
+ - name: Harden runner
37
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
38
+ with:
39
+ egress-policy: audit
40
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
41
+ with:
42
+ persist-credentials: false
43
+ - name: Apply curated notes
44
+ run: bash scripts/apply-release-notes.sh
@@ -0,0 +1,52 @@
1
+ name: Auto-approve
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, ready_for_review]
6
+ workflow_dispatch: {}
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: auto-approve-${{ github.event.pull_request.number || github.ref }}
13
+ cancel-in-progress: false
14
+
15
+ jobs:
16
+ auto-approve:
17
+ name: Auto-approve
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 5
20
+ permissions:
21
+ pull-requests: write
22
+ # Approve only. This repo has no GitHub App, and a GITHUB_TOKEN
23
+ # squash would skip the Release workflow on main.
24
+ if: >-
25
+ github.event_name == 'pull_request' &&
26
+ github.event.pull_request.head.repo.full_name == github.repository &&
27
+ github.event.pull_request.user.login != 'dependabot[bot]' &&
28
+ github.event.pull_request.user.login != 'github-actions[bot]' &&
29
+ (github.actor == 'SebTardif' || github.actor == 'minidb-release[bot]')
30
+ steps:
31
+ - name: Harden runner
32
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
33
+ with:
34
+ egress-policy: audit
35
+
36
+ - name: Approve pull request
37
+ env:
38
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39
+ PR_URL: ${{ github.event.pull_request.html_url }}
40
+ run: |
41
+ set -euo pipefail
42
+ if gh pr review --approve "$PR_URL"; then
43
+ echo "Approved"
44
+ exit 0
45
+ fi
46
+ echo "Approve returned non-zero; checking for an existing approval"
47
+ count=$(gh pr view "$PR_URL" --json reviews --jq '[.reviews[] | select(.state=="APPROVED")] | length')
48
+ echo "existing approvals=${count}"
49
+ if [ "$count" = "0" ]; then
50
+ echo "Pull request has no approving review"
51
+ exit 1
52
+ fi
@@ -0,0 +1,278 @@
1
+ name: CI
2
+
3
+ on:
4
+ # Recipe A: product tests on PR (and merge_group if a queue is added).
5
+ # Do not compile again on push to main. Release publish stays in release.yml.
6
+ # ready_for_review re-runs CI when a draft is marked ready.
7
+ pull_request:
8
+ branches: [main]
9
+ types: [opened, synchronize, reopened, ready_for_review]
10
+ merge_group: {}
11
+ schedule:
12
+ - cron: "17 6 * * 1" # Monday, after the 06:00 security scan
13
+ workflow_dispatch: {}
14
+
15
+ concurrency:
16
+ group: ci-${{ github.ref }}
17
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ jobs:
23
+ changes:
24
+ # Docs-only and draft pulls skip the test matrix. Schedule, dispatch,
25
+ # and merge_group skip this job, and downstream jobs then run.
26
+ runs-on: ubuntu-latest
27
+ timeout-minutes: 5
28
+ if: github.event_name == 'pull_request' && github.event.pull_request.draft == false
29
+ permissions:
30
+ pull-requests: read
31
+ outputs:
32
+ code: ${{ steps.filter.outputs.code }}
33
+ workflows: ${{ steps.filter.outputs.workflows }}
34
+ steps:
35
+ - name: Harden runner
36
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
37
+ with:
38
+ egress-policy: audit
39
+
40
+ - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
41
+ id: filter
42
+ with:
43
+ filters: |
44
+ code:
45
+ - 'minidb_sql/**'
46
+ - 'tests/**'
47
+ - 'scripts/**'
48
+ - 'pyproject.toml'
49
+ - 'main.py'
50
+ - '.github/actions/**'
51
+ - '.github/workflows/ci.yml'
52
+ workflows:
53
+ - '.github/workflows/**'
54
+ - '.github/actions/**'
55
+ - '.github/zizmor.yml'
56
+ - 'scripts/**'
57
+ - '.github/actionlint.yaml'
58
+
59
+ lint:
60
+ name: Lint & Format
61
+ needs: [changes]
62
+ if: >
63
+ always()
64
+ && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
65
+ && (needs.changes.result == 'skipped' || needs.changes.outputs.code == 'true')
66
+ runs-on: ubuntu-latest
67
+ timeout-minutes: 5
68
+ steps:
69
+ - name: Harden runner
70
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
71
+ with:
72
+ egress-policy: audit
73
+
74
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
75
+ with:
76
+ persist-credentials: false
77
+
78
+ - uses: ./.github/actions/setup-python
79
+ with:
80
+ python-version: "3.13"
81
+
82
+ - name: Install dependencies
83
+ run: pip install ruff==0.16.6
84
+
85
+ - name: Ruff check
86
+ run: ruff check .
87
+
88
+ - name: Ruff format check
89
+ run: ruff format --check .
90
+
91
+ type-check:
92
+ name: Type Check
93
+ needs: [changes]
94
+ if: >
95
+ always()
96
+ && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
97
+ && (needs.changes.result == 'skipped' || needs.changes.outputs.code == 'true')
98
+ runs-on: ubuntu-latest
99
+ timeout-minutes: 5
100
+ steps:
101
+ - name: Harden runner
102
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
103
+ with:
104
+ egress-policy: audit
105
+
106
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
107
+ with:
108
+ persist-credentials: false
109
+
110
+ - uses: ./.github/actions/setup-python
111
+ with:
112
+ python-version: "3.13"
113
+
114
+ - name: Install dependencies
115
+ run: pip install mypy
116
+
117
+ - name: Mypy
118
+ run: mypy minidb_sql/
119
+
120
+ test:
121
+ name: Test (Python ${{ matrix.python-version }})
122
+ needs: [changes]
123
+ if: >
124
+ always()
125
+ && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
126
+ && (needs.changes.result == 'skipped' || needs.changes.outputs.code == 'true')
127
+ runs-on: ubuntu-latest
128
+ timeout-minutes: 10
129
+ strategy:
130
+ fail-fast: false
131
+ matrix:
132
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
133
+ steps:
134
+ - name: Harden runner
135
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
136
+ with:
137
+ egress-policy: audit
138
+
139
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
140
+ with:
141
+ persist-credentials: false
142
+
143
+ - uses: ./.github/actions/setup-python
144
+ with:
145
+ python-version: ${{ matrix.python-version }}
146
+
147
+ - name: Install dependencies
148
+ run: pip install pytest pytest-cov
149
+
150
+ - name: Run tests with coverage
151
+ run: pytest tests/ --cov=minidb_sql --cov-report=term-missing --cov-report=xml
152
+
153
+ - name: Upload coverage
154
+ if: matrix.python-version == '3.13'
155
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
156
+ with:
157
+ name: coverage-report
158
+ path: coverage.xml
159
+
160
+ workflow-sanity:
161
+ name: Workflow sanity
162
+ needs: [changes]
163
+ if: >
164
+ always()
165
+ && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
166
+ && (needs.changes.result == 'skipped' || needs.changes.outputs.workflows == 'true')
167
+ runs-on: ubuntu-latest
168
+ timeout-minutes: 5
169
+ steps:
170
+ - name: Harden runner
171
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
172
+ with:
173
+ egress-policy: audit
174
+
175
+ - name: Checkout
176
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
177
+ with:
178
+ persist-credentials: false
179
+
180
+ - name: Install actionlint
181
+ run: |
182
+ set -euo pipefail
183
+ archive="actionlint_1.7.12_linux_amd64.tar.gz"
184
+ sha="8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8"
185
+ curl -sSfL "https://github.com/rhysd/actionlint/releases/download/v1.7.12/${archive}" \
186
+ -o "/tmp/${archive}"
187
+ echo "${sha} /tmp/${archive}" | sha256sum -c -
188
+ sudo tar -xzf "/tmp/${archive}" -C /usr/local/bin actionlint
189
+ actionlint -version
190
+
191
+ - name: Install zizmor
192
+ uses: taiki-e/install-action@5488ac5a951645ce95062214902ac4b6bc1a1037 # v2.87.32
193
+ with:
194
+ tool: zizmor@1.30.0
195
+
196
+ - name: actionlint
197
+ run: actionlint -color
198
+
199
+ - name: zizmor
200
+ run: zizmor --persona=regular --min-severity=medium .github/workflows .github/actions
201
+
202
+ - name: Lock Recipe A and notes-branch apply
203
+ run: |
204
+ python3 scripts/test_apply_release_notes.py
205
+ python3 scripts/test_workflow_triggers.py
206
+ python3 scripts/test_release_please.py
207
+ python3 scripts/test_check_dco.py
208
+ python3 scripts/test_report_scheduled_failure.py
209
+
210
+ ci:
211
+ name: ci
212
+ needs: [changes, lint, type-check, test, workflow-sanity]
213
+ if: always()
214
+ runs-on: ubuntu-latest
215
+ timeout-minutes: 5
216
+ steps:
217
+ - name: Harden runner
218
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
219
+ with:
220
+ egress-policy: audit
221
+
222
+ - name: Gate
223
+ env:
224
+ CHANGES: ${{ needs.changes.result }}
225
+ LINT: ${{ needs.lint.result }}
226
+ TYPE: ${{ needs.type-check.result }}
227
+ TEST: ${{ needs.test.result }}
228
+ SANITY: ${{ needs.workflow-sanity.result }}
229
+ run: |
230
+ set -euo pipefail
231
+ for result in "$CHANGES" "$LINT" "$TYPE" "$TEST" "$SANITY"; do
232
+ if [ "$result" = "failure" ] || [ "$result" = "cancelled" ] || [ "$result" = "abandoned" ]; then
233
+ echo "Upstream job did not succeed: $result"
234
+ exit 1
235
+ fi
236
+ done
237
+ echo "ci gate passed"
238
+
239
+ report-failure:
240
+ name: Report CI failure
241
+ needs: [changes, lint, type-check, test, workflow-sanity]
242
+ if: always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
243
+ runs-on: ubuntu-latest
244
+ timeout-minutes: 5
245
+ permissions:
246
+ contents: read
247
+ issues: write
248
+ steps:
249
+ - name: Harden runner
250
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
251
+ with:
252
+ egress-policy: audit
253
+
254
+ - name: Checkout
255
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
256
+ with:
257
+ persist-credentials: false
258
+
259
+ - name: Open or close the failure issue
260
+ env:
261
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
262
+ GH_REPO: ${{ github.repository }}
263
+ ASSIGNEE: ${{ vars.NIGHTLY_FAILURE_ASSIGNEE || 'SebTardif' }}
264
+ RUN_ID: ${{ github.run_id }}
265
+ RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
266
+ JOB_RESULTS: >-
267
+ changes=${{ needs.changes.result }}
268
+ lint=${{ needs.lint.result }}
269
+ type-check=${{ needs.type-check.result }}
270
+ test=${{ needs.test.result }}
271
+ workflow-sanity=${{ needs.workflow-sanity.result }}
272
+ run: |
273
+ python3 scripts/report-scheduled-failure.py \
274
+ --prefix "CI red" \
275
+ --run-id "$RUN_ID" \
276
+ --run-url "$RUN_URL" \
277
+ --label nightly-failure \
278
+ --label ready
@@ -0,0 +1,36 @@
1
+ name: DCO
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ merge_group: {}
7
+ workflow_dispatch: {}
8
+
9
+ concurrency:
10
+ group: dco-${{ github.ref }}
11
+ cancel-in-progress: false
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ dco:
18
+ name: DCO Sign-off
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 5
21
+ steps:
22
+ - name: Harden runner
23
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
24
+ with:
25
+ egress-policy: audit
26
+
27
+ - name: Checkout
28
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29
+ with:
30
+ persist-credentials: false
31
+ fetch-depth: 0
32
+
33
+ - name: Check DCO sign-off
34
+ env:
35
+ BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.sha }}
36
+ run: bash scripts/check-dco.sh
@@ -0,0 +1,90 @@
1
+ name: Dependabot auto-merge
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [opened, synchronize, reopened, ready_for_review]
6
+ workflow_dispatch: {}
7
+
8
+ concurrency:
9
+ group: dependabot-auto-merge-${{ github.event.pull_request.number || github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ auto-merge:
17
+ name: Auto-merge Dependabot PRs
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 5
20
+ # pull_request_target runs this file from main. Do not check out the
21
+ # pull request head. Metadata and gh only read the event payload.
22
+ if: >-
23
+ github.event_name == 'pull_request_target' &&
24
+ github.event.pull_request.user.login == 'dependabot[bot]' &&
25
+ github.event.pull_request.head.repo.full_name == github.repository
26
+ permissions:
27
+ contents: write
28
+ pull-requests: write
29
+ steps:
30
+ - name: Harden runner
31
+ uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
32
+ with:
33
+ egress-policy: audit
34
+
35
+ - name: Fetch Dependabot metadata
36
+ id: metadata
37
+ uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3
38
+ with:
39
+ github-token: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ - name: Detect a SHA pin labeled as a major
42
+ id: sha-pin
43
+ env:
44
+ PREV: ${{ steps.metadata.outputs.previous-version }}
45
+ DEPS: ${{ steps.metadata.outputs.updated-dependencies-json }}
46
+ run: |
47
+ set -euo pipefail
48
+ sha=false
49
+ if [ -n "${DEPS}" ] && [ "${DEPS}" != "null" ]; then
50
+ if printf '%s' "$DEPS" | jq -e '
51
+ type == "array" and length > 0 and
52
+ all(.[]; (.prevVersion // "") | test("^[0-9a-f]{40}$"))
53
+ ' >/dev/null; then
54
+ sha=true
55
+ fi
56
+ elif printf '%s' "$PREV" | grep -Eq '^[0-9a-f]{40}$'; then
57
+ sha=true
58
+ fi
59
+ echo "sha=${sha}" >> "$GITHUB_OUTPUT"
60
+
61
+ - name: Approve and enable auto-merge
62
+ if: >-
63
+ (steps.metadata.outputs.update-type != 'version-update:semver-major' ||
64
+ steps.sha-pin.outputs.sha == 'true') &&
65
+ github.event.pull_request.draft == false
66
+ env:
67
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68
+ PR_URL: ${{ github.event.pull_request.html_url }}
69
+ run: |
70
+ set -euo pipefail
71
+ if ! gh pr review --approve "$PR_URL"; then
72
+ echo "Approve returned non-zero; continuing when a review is already present"
73
+ fi
74
+ if gh pr merge --auto --squash "$PR_URL"; then
75
+ echo "Auto-merge enabled"
76
+ exit 0
77
+ fi
78
+ enabled=$(gh pr view "$PR_URL" --json autoMergeRequest,state --jq 'if .state=="OPEN" and .autoMergeRequest!=null then "yes" else "no" end')
79
+ if [ "$enabled" = "yes" ]; then
80
+ echo "Auto-merge was already enabled"
81
+ exit 0
82
+ fi
83
+ echo "Failed to enable auto-merge"
84
+ exit 1
85
+
86
+ - name: Skip major updates
87
+ if: >-
88
+ steps.metadata.outputs.update-type == 'version-update:semver-major' &&
89
+ steps.sha-pin.outputs.sha != 'true'
90
+ run: echo "Skipping major version update; requires manual review"