blackboardxray 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.
- blackboardxray-0.1.0/.editorconfig +22 -0
- blackboardxray-0.1.0/.gitattributes +20 -0
- blackboardxray-0.1.0/.github/ISSUE_TEMPLATE/bug.yml +80 -0
- blackboardxray-0.1.0/.github/ISSUE_TEMPLATE/config.yml +16 -0
- blackboardxray-0.1.0/.github/ISSUE_TEMPLATE/feature.yml +46 -0
- blackboardxray-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +34 -0
- blackboardxray-0.1.0/.github/dependabot.yml +44 -0
- blackboardxray-0.1.0/.github/workflows/ci.yml +136 -0
- blackboardxray-0.1.0/.github/workflows/release.yml +167 -0
- blackboardxray-0.1.0/.github/workflows/security.yml +92 -0
- blackboardxray-0.1.0/.github/workflows/title-lint.yml +79 -0
- blackboardxray-0.1.0/.gitignore +26 -0
- blackboardxray-0.1.0/.pre-commit-config.yaml +49 -0
- blackboardxray-0.1.0/.release-please-manifest.json +3 -0
- blackboardxray-0.1.0/CHANGELOG.md +34 -0
- blackboardxray-0.1.0/CODE_OF_CONDUCT.md +129 -0
- blackboardxray-0.1.0/CONTRIBUTING.md +101 -0
- blackboardxray-0.1.0/Dockerfile +32 -0
- blackboardxray-0.1.0/LICENSE +202 -0
- blackboardxray-0.1.0/Makefile +45 -0
- blackboardxray-0.1.0/PKG-INFO +232 -0
- blackboardxray-0.1.0/PLAN.md +273 -0
- blackboardxray-0.1.0/README.md +207 -0
- blackboardxray-0.1.0/SECURITY.md +102 -0
- blackboardxray-0.1.0/docker-compose.yml +75 -0
- blackboardxray-0.1.0/docs/adr/0001-scope.md +49 -0
- blackboardxray-0.1.0/docs/adr/0002-one-database.md +42 -0
- blackboardxray-0.1.0/docs/adr/0003-sessions-not-tokens.md +40 -0
- blackboardxray-0.1.0/docs/adr/0004-invite-links-not-email.md +31 -0
- blackboardxray-0.1.0/docs/architecture.md +107 -0
- blackboardxray-0.1.0/docs/design/brand.md +87 -0
- blackboardxray-0.1.0/docs/design/objects.md +151 -0
- blackboardxray-0.1.0/docs/design/rules.md +127 -0
- blackboardxray-0.1.0/docs/design-system.md +284 -0
- blackboardxray-0.1.0/docs/limits.md +92 -0
- blackboardxray-0.1.0/docs/product.md +89 -0
- blackboardxray-0.1.0/docs/self-hosting.md +192 -0
- blackboardxray-0.1.0/examples/backfill.py +242 -0
- blackboardxray-0.1.0/examples/seed.py +248 -0
- blackboardxray-0.1.0/pyproject.toml +96 -0
- blackboardxray-0.1.0/release-please-config.json +23 -0
- blackboardxray-0.1.0/src/blackboardxray/__init__.py +58 -0
- blackboardxray-0.1.0/src/blackboardxray/_transport.py +381 -0
- blackboardxray-0.1.0/src/blackboardxray/events.py +223 -0
- blackboardxray-0.1.0/src/blackboardxray/observe.py +671 -0
- blackboardxray-0.1.0/src/blackboardxray/py.typed +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/__init__.py +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/__main__.py +123 -0
- blackboardxray-0.1.0/src/blackboardxray/server/app.py +261 -0
- blackboardxray-0.1.0/src/blackboardxray/server/db.py +672 -0
- blackboardxray-0.1.0/src/blackboardxray/server/identity.py +180 -0
- blackboardxray-0.1.0/src/blackboardxray/server/limits.py +88 -0
- blackboardxray-0.1.0/src/blackboardxray/server/migrate.py +184 -0
- blackboardxray-0.1.0/src/blackboardxray/server/migrations/0001_initial.sql +101 -0
- blackboardxray-0.1.0/src/blackboardxray/server/migrations/0002_people_and_organizations.sql +155 -0
- blackboardxray-0.1.0/src/blackboardxray/server/migrations/0003_audit.sql +27 -0
- blackboardxray-0.1.0/src/blackboardxray/server/people.py +811 -0
- blackboardxray-0.1.0/src/blackboardxray/server/provision.py +113 -0
- blackboardxray-0.1.0/src/blackboardxray/server/roles.py +140 -0
- blackboardxray-0.1.0/src/blackboardxray/server/routes/__init__.py +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/routes/admin.py +378 -0
- blackboardxray-0.1.0/src/blackboardxray/server/routes/auth.py +345 -0
- blackboardxray-0.1.0/src/blackboardxray/server/routes/data.py +215 -0
- blackboardxray-0.1.0/src/blackboardxray/server/security.py +218 -0
- blackboardxray-0.1.0/src/blackboardxray/server/settings.py +123 -0
- blackboardxray-0.1.0/src/blackboardxray/server/upkeep.py +155 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/index-BJnByUnU.css +1 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/assets/index-Dp4Jd2bK.js +217 -0
- blackboardxray-0.1.0/src/blackboardxray/server/web/index.html +28 -0
- blackboardxray-0.1.0/tests/conftest.py +48 -0
- blackboardxray-0.1.0/tests/test_access.py +286 -0
- blackboardxray-0.1.0/tests/test_events.py +116 -0
- blackboardxray-0.1.0/tests/test_identity.py +193 -0
- blackboardxray-0.1.0/tests/test_migrate.py +308 -0
- blackboardxray-0.1.0/tests/test_observe.py +489 -0
- blackboardxray-0.1.0/tests/test_onboarding.py +233 -0
- blackboardxray-0.1.0/tests/test_people.py +384 -0
- blackboardxray-0.1.0/tests/test_server.py +573 -0
- blackboardxray-0.1.0/tests/test_transport.py +171 -0
- blackboardxray-0.1.0/tests/test_upkeep.py +242 -0
- blackboardxray-0.1.0/tests/test_wire_mirror.py +53 -0
- blackboardxray-0.1.0/ui/index.html +27 -0
- blackboardxray-0.1.0/ui/package-lock.json +3510 -0
- blackboardxray-0.1.0/ui/package.json +43 -0
- blackboardxray-0.1.0/ui/scripts/build-tokens.mjs +318 -0
- blackboardxray-0.1.0/ui/scripts/check-contrast.mjs +167 -0
- blackboardxray-0.1.0/ui/scripts/check-raw-values.mjs +76 -0
- blackboardxray-0.1.0/ui/shots.mjs +58 -0
- blackboardxray-0.1.0/ui/src/App.tsx +112 -0
- blackboardxray-0.1.0/ui/src/components/BoardContents.tsx +165 -0
- blackboardxray-0.1.0/ui/src/components/BoardTable.tsx +211 -0
- blackboardxray-0.1.0/ui/src/components/Dot.tsx +42 -0
- blackboardxray-0.1.0/ui/src/components/EventTable.tsx +181 -0
- blackboardxray-0.1.0/ui/src/components/Facets.tsx +167 -0
- blackboardxray-0.1.0/ui/src/components/Form.tsx +164 -0
- blackboardxray-0.1.0/ui/src/components/Frame.tsx +335 -0
- blackboardxray-0.1.0/ui/src/components/Histogram.tsx +296 -0
- blackboardxray-0.1.0/ui/src/components/Inspector.tsx +338 -0
- blackboardxray-0.1.0/ui/src/components/RunGraph.tsx +485 -0
- blackboardxray-0.1.0/ui/src/components/RunTimeline.tsx +165 -0
- blackboardxray-0.1.0/ui/src/lib/admin.ts +230 -0
- blackboardxray-0.1.0/ui/src/lib/api.ts +315 -0
- blackboardxray-0.1.0/ui/src/lib/cn.ts +7 -0
- blackboardxray-0.1.0/ui/src/lib/events.ts +218 -0
- blackboardxray-0.1.0/ui/src/lib/format.ts +108 -0
- blackboardxray-0.1.0/ui/src/lib/http.ts +94 -0
- blackboardxray-0.1.0/ui/src/lib/query.ts +161 -0
- blackboardxray-0.1.0/ui/src/lib/session.tsx +222 -0
- blackboardxray-0.1.0/ui/src/lib/theme.ts +34 -0
- blackboardxray-0.1.0/ui/src/main.tsx +40 -0
- blackboardxray-0.1.0/ui/src/routes/Account.tsx +183 -0
- blackboardxray-0.1.0/ui/src/routes/Agents.tsx +175 -0
- blackboardxray-0.1.0/ui/src/routes/Board.tsx +148 -0
- blackboardxray-0.1.0/ui/src/routes/Boards.tsx +176 -0
- blackboardxray-0.1.0/ui/src/routes/Gate.tsx +369 -0
- blackboardxray-0.1.0/ui/src/routes/OrgSettings.tsx +404 -0
- blackboardxray-0.1.0/ui/src/routes/Platform.tsx +122 -0
- blackboardxray-0.1.0/ui/src/routes/ProjectSettings.tsx +293 -0
- blackboardxray-0.1.0/ui/src/styles/app.css +244 -0
- blackboardxray-0.1.0/ui/src/vite-env.d.ts +1 -0
- blackboardxray-0.1.0/ui/tokens/primitive/breakpoint.json +11 -0
- blackboardxray-0.1.0/ui/tokens/primitive/elevation.json +17 -0
- blackboardxray-0.1.0/ui/tokens/primitive/focus.json +8 -0
- blackboardxray-0.1.0/ui/tokens/primitive/material.json +72 -0
- blackboardxray-0.1.0/ui/tokens/primitive/motion.json +40 -0
- blackboardxray-0.1.0/ui/tokens/primitive/radius.json +11 -0
- blackboardxray-0.1.0/ui/tokens/primitive/space.json +16 -0
- blackboardxray-0.1.0/ui/tokens/primitive/type.json +84 -0
- blackboardxray-0.1.0/ui/tokens/primitive/zindex.json +12 -0
- blackboardxray-0.1.0/ui/tokens/semantic/color.dark.json +119 -0
- blackboardxray-0.1.0/ui/tokens/semantic/color.light.json +119 -0
- blackboardxray-0.1.0/ui/tokens/semantic/space.json +160 -0
- blackboardxray-0.1.0/ui/tokens/semantic/type.json +12 -0
- blackboardxray-0.1.0/ui/tsconfig.app.json +24 -0
- blackboardxray-0.1.0/ui/tsconfig.app.tsbuildinfo +1 -0
- blackboardxray-0.1.0/ui/tsconfig.json +7 -0
- blackboardxray-0.1.0/ui/tsconfig.node.json +16 -0
- blackboardxray-0.1.0/ui/tsconfig.node.tsbuildinfo +1 -0
- blackboardxray-0.1.0/ui/vite.config.ts +20 -0
- blackboardxray-0.1.0/uv.lock +1184 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# One answer per file type, so an editor does not have to guess and a diff does
|
|
2
|
+
# not carry somebody else's settings.
|
|
3
|
+
root = true
|
|
4
|
+
|
|
5
|
+
[*]
|
|
6
|
+
charset = utf-8
|
|
7
|
+
end_of_line = lf
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
indent_style = space
|
|
11
|
+
indent_size = 4
|
|
12
|
+
|
|
13
|
+
[*.{js,jsx,ts,tsx,json,jsonc,css,html,yml,yaml,mjs}]
|
|
14
|
+
indent_size = 2
|
|
15
|
+
|
|
16
|
+
[*.md]
|
|
17
|
+
# A trailing double space is a line break in Markdown, and trimming it changes
|
|
18
|
+
# what the document says.
|
|
19
|
+
trim_trailing_whitespace = false
|
|
20
|
+
|
|
21
|
+
[Makefile]
|
|
22
|
+
indent_style = tab
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# One line ending everywhere, decided here rather than by whichever machine
|
|
2
|
+
# checked the file out.
|
|
3
|
+
* text=auto eol=lf
|
|
4
|
+
|
|
5
|
+
# Generated. Marked so a diff view collapses them and a language survey does not
|
|
6
|
+
# count them as something somebody wrote.
|
|
7
|
+
CHANGELOG.md linguist-generated=true
|
|
8
|
+
uv.lock linguist-generated=true -diff
|
|
9
|
+
ui/package-lock.json linguist-generated=true -diff
|
|
10
|
+
ui/src/styles/tokens.css linguist-generated=true -diff
|
|
11
|
+
ui/src/styles/theme.css linguist-generated=true -diff
|
|
12
|
+
ui/tokens/primitive/color.json linguist-generated=true -diff
|
|
13
|
+
|
|
14
|
+
# Not the product. The interface's own source is, but its lockfile is not, and
|
|
15
|
+
# the fixtures are not.
|
|
16
|
+
examples/** linguist-documentation=true
|
|
17
|
+
docs/** linguist-documentation=true
|
|
18
|
+
|
|
19
|
+
*.png binary
|
|
20
|
+
*.woff2 binary
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something behaves differently from what it says it does
|
|
3
|
+
labels: ["type:fix"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thank you for the report. The two fields that matter most are what you
|
|
9
|
+
expected and what happened, in that order.
|
|
10
|
+
|
|
11
|
+
If this is a security vulnerability, do not open an issue. `SECURITY.md`
|
|
12
|
+
says where to send it privately.
|
|
13
|
+
|
|
14
|
+
- type: textarea
|
|
15
|
+
id: expected
|
|
16
|
+
attributes:
|
|
17
|
+
label: What you expected
|
|
18
|
+
description: What should have happened, and what made you expect it.
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: happened
|
|
24
|
+
attributes:
|
|
25
|
+
label: What happened instead
|
|
26
|
+
description: Include the exact error or the exact wrong value, not a paraphrase.
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: reproduce
|
|
32
|
+
attributes:
|
|
33
|
+
label: How to see it
|
|
34
|
+
description: >
|
|
35
|
+
The shortest path from a fresh install to the wrong behaviour. A failing
|
|
36
|
+
test is the best possible version of this.
|
|
37
|
+
placeholder: |
|
|
38
|
+
1. docker compose up -d
|
|
39
|
+
2. Set up, then ...
|
|
40
|
+
3. The runs list shows ...
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
43
|
+
|
|
44
|
+
- type: dropdown
|
|
45
|
+
id: where
|
|
46
|
+
attributes:
|
|
47
|
+
label: Where
|
|
48
|
+
options:
|
|
49
|
+
- The server or the API
|
|
50
|
+
- The interface
|
|
51
|
+
- The client that sends events
|
|
52
|
+
- Installing or upgrading
|
|
53
|
+
- Somewhere else, or not sure
|
|
54
|
+
validations:
|
|
55
|
+
required: true
|
|
56
|
+
|
|
57
|
+
- type: input
|
|
58
|
+
id: version
|
|
59
|
+
attributes:
|
|
60
|
+
label: Version
|
|
61
|
+
description: >
|
|
62
|
+
The image tag, or `pip show blackboardxray`, or the commit you are on.
|
|
63
|
+
placeholder: "0.1.0, or ghcr.io/moeinroghani/blackboardxray:1"
|
|
64
|
+
validations:
|
|
65
|
+
required: true
|
|
66
|
+
|
|
67
|
+
- type: input
|
|
68
|
+
id: postgres
|
|
69
|
+
attributes:
|
|
70
|
+
label: Postgres version
|
|
71
|
+
placeholder: "17.2"
|
|
72
|
+
|
|
73
|
+
- type: textarea
|
|
74
|
+
id: logs
|
|
75
|
+
attributes:
|
|
76
|
+
label: Logs
|
|
77
|
+
description: >
|
|
78
|
+
`docker compose logs xray`, or the server's output. Take the request
|
|
79
|
+
identifier out of the failing response if you have it.
|
|
80
|
+
render: text
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Question, or an idea you want to talk through
|
|
4
|
+
url: https://github.com/MoeinRoghani/blackboardxray/discussions
|
|
5
|
+
about: >
|
|
6
|
+
Discussions, rather than the issue tracker. An issue is a thing to be
|
|
7
|
+
done; a question is not, and it gets a better answer there.
|
|
8
|
+
- name: Security vulnerability
|
|
9
|
+
url: https://github.com/MoeinRoghani/blackboardxray/security/advisories/new
|
|
10
|
+
about: >
|
|
11
|
+
Report it privately. Please do not open an issue for a vulnerability.
|
|
12
|
+
- name: How to run this yourself
|
|
13
|
+
url: https://github.com/MoeinRoghani/blackboardxray/blob/main/docs/self-hosting.md
|
|
14
|
+
about: >
|
|
15
|
+
Every environment variable, the proxy headers that matter, backup,
|
|
16
|
+
upgrading, and what this deliberately does not do.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Something this should do and does not
|
|
3
|
+
labels: ["type:feat"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
The most useful requests describe a problem rather than a solution. What
|
|
9
|
+
you cannot currently find out about a run is more actionable than which
|
|
10
|
+
control you would like added.
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: problem
|
|
14
|
+
attributes:
|
|
15
|
+
label: What you cannot do today
|
|
16
|
+
description: The situation you are in and what you end up doing instead.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: shape
|
|
22
|
+
attributes:
|
|
23
|
+
label: What would solve it
|
|
24
|
+
description: >
|
|
25
|
+
If you have a shape in mind, describe it. If you do not, say so; that is
|
|
26
|
+
a legitimate answer and often a better one.
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: considered
|
|
32
|
+
attributes:
|
|
33
|
+
label: What you have already tried
|
|
34
|
+
description: >
|
|
35
|
+
Including whether an existing view nearly does it. Knowing what nearly
|
|
36
|
+
works says more than a blank field.
|
|
37
|
+
|
|
38
|
+
- type: checkboxes
|
|
39
|
+
id: scope
|
|
40
|
+
attributes:
|
|
41
|
+
label: Before you send this
|
|
42
|
+
options:
|
|
43
|
+
- label: >
|
|
44
|
+
I have read the end of `docs/self-hosting.md`, and this is not one of
|
|
45
|
+
the things the project has deliberately decided not to do.
|
|
46
|
+
required: true
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- What is different afterwards, for somebody using this. One or two
|
|
4
|
+
sentences. The title is the release note; this is the reason. -->
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
<!-- The problem. If there is an issue, say `Closes #N` and this can be short. -->
|
|
9
|
+
|
|
10
|
+
Closes #
|
|
11
|
+
|
|
12
|
+
## How it was checked
|
|
13
|
+
|
|
14
|
+
<!-- What you ran, and what a reviewer should run to see it. If this fixes a
|
|
15
|
+
bug, name the test that failed before the change. -->
|
|
16
|
+
|
|
17
|
+
- [ ] `make verify` passes with `BLACKBOARDXRAY_TEST_DSN` set to a real database
|
|
18
|
+
- [ ] A test fails against the unmodified code and passes against this one
|
|
19
|
+
- [ ] The documentation this affects is updated in this pull request
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<!--
|
|
24
|
+
Two things this body must satisfy, both checked by a workflow.
|
|
25
|
+
|
|
26
|
+
NO PARENTHESES. The squash merge writes this body into the commit message and
|
|
27
|
+
release-please parses that message. A parenthesis defeats its parser silently:
|
|
28
|
+
the commit is dropped from the release notes while every check stays green.
|
|
29
|
+
Commas, semicolons and separate sentences carry the same meaning.
|
|
30
|
+
|
|
31
|
+
A BREAKING CHANGE carries both a `!` in the title and a `BREAKING CHANGE:`
|
|
32
|
+
footer here, stating what changed and what a caller writes instead. Both, not
|
|
33
|
+
either.
|
|
34
|
+
-->
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Four ecosystems, because this project has four. The interface has its own
|
|
2
|
+
# dependency tree and would otherwise never be updated, and the base images in
|
|
3
|
+
# the Dockerfile age the same way a package does.
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
- package-ecosystem: "uv"
|
|
7
|
+
directory: "/"
|
|
8
|
+
schedule:
|
|
9
|
+
interval: "weekly"
|
|
10
|
+
commit-message:
|
|
11
|
+
prefix: "build"
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "npm"
|
|
14
|
+
directory: "/ui"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
commit-message:
|
|
18
|
+
prefix: "build"
|
|
19
|
+
groups:
|
|
20
|
+
# One pull request for the interface's development tooling rather than
|
|
21
|
+
# one per package. They move together and are checked by the same build.
|
|
22
|
+
interface-tooling:
|
|
23
|
+
patterns:
|
|
24
|
+
- "@types/*"
|
|
25
|
+
- "typescript"
|
|
26
|
+
- "vite"
|
|
27
|
+
- "@vitejs/*"
|
|
28
|
+
- "tailwindcss"
|
|
29
|
+
- "@tailwindcss/*"
|
|
30
|
+
- "playwright"
|
|
31
|
+
|
|
32
|
+
- package-ecosystem: "github-actions"
|
|
33
|
+
directory: "/"
|
|
34
|
+
schedule:
|
|
35
|
+
interval: "weekly"
|
|
36
|
+
commit-message:
|
|
37
|
+
prefix: "ci"
|
|
38
|
+
|
|
39
|
+
- package-ecosystem: "docker"
|
|
40
|
+
directory: "/"
|
|
41
|
+
schedule:
|
|
42
|
+
interval: "weekly"
|
|
43
|
+
commit-message:
|
|
44
|
+
prefix: "build"
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
python:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
python: ["3.11", "3.12", "3.13"]
|
|
19
|
+
services:
|
|
20
|
+
postgres:
|
|
21
|
+
image: postgres:17
|
|
22
|
+
env:
|
|
23
|
+
POSTGRES_USER: xray
|
|
24
|
+
POSTGRES_PASSWORD: xray
|
|
25
|
+
POSTGRES_DB: xray_test
|
|
26
|
+
ports: ["5432:5432"]
|
|
27
|
+
options: >-
|
|
28
|
+
--health-cmd pg_isready
|
|
29
|
+
--health-interval 5s
|
|
30
|
+
--health-timeout 3s
|
|
31
|
+
--health-retries 10
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
34
|
+
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python }}
|
|
37
|
+
# From the lockfile, into a virtual environment. `--system` installs into
|
|
38
|
+
# the runner's own interpreter, which Debian marks externally managed and
|
|
39
|
+
# refuses, and `--frozen` is what makes this run the versions the lock
|
|
40
|
+
# names rather than whatever resolved this morning.
|
|
41
|
+
- run: uv sync --frozen --python ${{ matrix.python }}
|
|
42
|
+
- run: uv run ruff check src tests examples
|
|
43
|
+
- run: uv run ruff format --check src tests examples
|
|
44
|
+
- run: uv run mypy src
|
|
45
|
+
# The database tests skip where no server is named. Naming one here is
|
|
46
|
+
# what stops them silently skipping in the only place it matters.
|
|
47
|
+
- name: The suite, against a real Postgres
|
|
48
|
+
run: |
|
|
49
|
+
uv run pytest -q --strict-markers 2>&1 | tee /tmp/out
|
|
50
|
+
if grep -qE "[0-9]+ skipped" /tmp/out; then
|
|
51
|
+
echo
|
|
52
|
+
echo "A test skipped. Every skip in this suite means the database"
|
|
53
|
+
echo "was not reachable, which makes a green run a green run of"
|
|
54
|
+
echo "about a third of what there is."
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
env:
|
|
58
|
+
BLACKBOARDXRAY_TEST_DSN: postgresql://xray:xray@localhost:5432/xray_test
|
|
59
|
+
|
|
60
|
+
interface:
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
64
|
+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
65
|
+
with:
|
|
66
|
+
node-version: "24"
|
|
67
|
+
- run: npm install
|
|
68
|
+
working-directory: ui
|
|
69
|
+
# The token pipeline, the raw-value gate, the contrast gate, and tsc.
|
|
70
|
+
# A screen that sets a value or a pair below its contrast floor fails here.
|
|
71
|
+
- run: npm run verify
|
|
72
|
+
working-directory: ui
|
|
73
|
+
- run: npm run build
|
|
74
|
+
working-directory: ui
|
|
75
|
+
|
|
76
|
+
# What `pip install blackboardxray[server]` actually gets. The interface
|
|
77
|
+
# is generated and gitignored, and a build backend that skips what
|
|
78
|
+
# version control ignores ships a server serving a blank page. It has
|
|
79
|
+
# happened twice: once because the wheel target did not name it, and
|
|
80
|
+
# once because the sdist did not and the wheel is built from the sdist.
|
|
81
|
+
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
|
|
82
|
+
with:
|
|
83
|
+
python-version: "3.12"
|
|
84
|
+
- name: the interface is in both distributions
|
|
85
|
+
run: |
|
|
86
|
+
set -euo pipefail
|
|
87
|
+
uv build
|
|
88
|
+
# Listed to a file first. `grep -q` exits on its first match and
|
|
89
|
+
# closes the pipe, `tar` then fails writing to it, and `pipefail`
|
|
90
|
+
# fails the step for a check that actually passed.
|
|
91
|
+
tar tzf dist/*.tar.gz > /tmp/sdist.txt
|
|
92
|
+
unzip -l dist/*.whl > /tmp/wheel.txt
|
|
93
|
+
grep -q "server/web/index.html" /tmp/sdist.txt
|
|
94
|
+
echo "the sdist carries the interface"
|
|
95
|
+
grep -q "server/web/index.html" /tmp/wheel.txt
|
|
96
|
+
test "$(grep -c "server/web/assets/" /tmp/wheel.txt)" -gt 0
|
|
97
|
+
echo "the wheel carries the interface and its assets"
|
|
98
|
+
|
|
99
|
+
# The quickstart in the README, run as written. A compose file that has drifted
|
|
100
|
+
# from the Dockerfile is a first impression nobody recovers from, and it is
|
|
101
|
+
# exactly the kind of break the unit tests cannot see.
|
|
102
|
+
compose:
|
|
103
|
+
runs-on: ubuntu-latest
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
106
|
+
- run: docker compose up -d --build --wait --wait-timeout 300
|
|
107
|
+
- name: The platform answers and says it needs setting up
|
|
108
|
+
run: |
|
|
109
|
+
set -euo pipefail
|
|
110
|
+
test "$(curl -sf localhost:8900/api/v1/ready | jq -r .status)" = ready
|
|
111
|
+
test "$(curl -sf localhost:8900/api/v1/auth/state | jq -r .needs_setup)" = true
|
|
112
|
+
- name: The first run makes an owner, a project and a key that sends
|
|
113
|
+
run: |
|
|
114
|
+
set -euo pipefail
|
|
115
|
+
key=$(curl -sf -X POST localhost:8900/api/v1/setup \
|
|
116
|
+
-H 'content-type: application/json' \
|
|
117
|
+
-H 'origin: http://localhost:8900' \
|
|
118
|
+
-d '{"email":"ci@example.com","password":"a long enough phrase",
|
|
119
|
+
"organization":"CI","project":"Production"}' | jq -r .api_key)
|
|
120
|
+
test -n "$key"
|
|
121
|
+
curl -sf -X POST localhost:8900/api/v1/ingest \
|
|
122
|
+
-H "authorization: Bearer $key" -H 'content-type: application/json' \
|
|
123
|
+
-d '{"events":[{"board_id":"ci-1","kind":"run.opened"}]}' \
|
|
124
|
+
| jq -e '.stored == 1'
|
|
125
|
+
- name: Reading without a session is refused
|
|
126
|
+
run: |
|
|
127
|
+
set -euo pipefail
|
|
128
|
+
code=$(curl -s -o /dev/null -w '%{http_code}' \
|
|
129
|
+
localhost:8900/api/v1/projects/proj_nothing/overview)
|
|
130
|
+
test "$code" = 401
|
|
131
|
+
- name: The interface is served, not just the API
|
|
132
|
+
run: curl -sf localhost:8900/ | grep -q "<div id=\"root\">"
|
|
133
|
+
- if: failure()
|
|
134
|
+
run: docker compose logs --no-color | tail -80
|
|
135
|
+
- if: always()
|
|
136
|
+
run: docker compose down -v
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# What a tag does.
|
|
2
|
+
#
|
|
3
|
+
# release-please keeps the version and the changelog from the commit subjects
|
|
4
|
+
# on main, and opens a pull request that holds them. Merging that pull request
|
|
5
|
+
# tags the release, and the tag builds the image and publishes the client.
|
|
6
|
+
#
|
|
7
|
+
# Nothing here is done by a person, because a release done by hand is a release
|
|
8
|
+
# whose steps are remembered differently each time. The one exception is the
|
|
9
|
+
# recovery path: a tag whose artefacts failed to publish can be published again
|
|
10
|
+
# without cutting a second tag, which is what `workflow_dispatch` is for.
|
|
11
|
+
name: Release
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
inputs:
|
|
18
|
+
tag:
|
|
19
|
+
description: "An existing tag to publish, when its artefacts failed"
|
|
20
|
+
required: true
|
|
21
|
+
type: string
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
# This job always runs and its one step does not. A skipped job propagates
|
|
28
|
+
# its skip down the whole needs chain, and overriding that in each job below
|
|
29
|
+
# was tried and did not work; having nothing skipped is simpler than
|
|
30
|
+
# explaining to every downstream job that a skip upstream was expected.
|
|
31
|
+
please:
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
permissions:
|
|
34
|
+
contents: write
|
|
35
|
+
pull-requests: write
|
|
36
|
+
outputs:
|
|
37
|
+
released: ${{ steps.please.outputs.release_created }}
|
|
38
|
+
tag: ${{ steps.please.outputs.tag_name }}
|
|
39
|
+
steps:
|
|
40
|
+
- uses: googleapis/release-please-action@a02a34c4d625f9be7cb89156071d8567266a2445 # v4.1.3
|
|
41
|
+
id: please
|
|
42
|
+
if: github.event_name == 'push'
|
|
43
|
+
with:
|
|
44
|
+
config-file: release-please-config.json
|
|
45
|
+
manifest-file: .release-please-manifest.json
|
|
46
|
+
|
|
47
|
+
# What to publish, from whichever of the two ways this ran. One job, so the
|
|
48
|
+
# two below say `needs.plan` and never care which it was.
|
|
49
|
+
plan:
|
|
50
|
+
needs: [please]
|
|
51
|
+
if: needs.please.outputs.released == 'true' || github.event_name == 'workflow_dispatch'
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
outputs:
|
|
54
|
+
tag: ${{ steps.what.outputs.tag }}
|
|
55
|
+
version: ${{ steps.what.outputs.version }}
|
|
56
|
+
major: ${{ steps.what.outputs.major }}
|
|
57
|
+
minor: ${{ steps.what.outputs.minor }}
|
|
58
|
+
steps:
|
|
59
|
+
- id: what
|
|
60
|
+
env:
|
|
61
|
+
TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || needs.please.outputs.tag }}
|
|
62
|
+
run: |
|
|
63
|
+
set -euo pipefail
|
|
64
|
+
version="${TAG#v}"
|
|
65
|
+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
66
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
67
|
+
echo "major=${version%%.*}" >> "$GITHUB_OUTPUT"
|
|
68
|
+
rest="${version#*.}"
|
|
69
|
+
echo "minor=${rest%%.*}" >> "$GITHUB_OUTPUT"
|
|
70
|
+
|
|
71
|
+
image:
|
|
72
|
+
needs: [plan]
|
|
73
|
+
runs-on: ubuntu-latest
|
|
74
|
+
permissions:
|
|
75
|
+
contents: read
|
|
76
|
+
packages: write
|
|
77
|
+
# Signing the provenance attestation.
|
|
78
|
+
id-token: write
|
|
79
|
+
attestations: write
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
82
|
+
with:
|
|
83
|
+
ref: ${{ needs.plan.outputs.tag }}
|
|
84
|
+
- uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
|
|
85
|
+
- uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
|
|
86
|
+
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
|
87
|
+
with:
|
|
88
|
+
registry: ghcr.io
|
|
89
|
+
username: ${{ github.actor }}
|
|
90
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
91
|
+
|
|
92
|
+
# A registry name must be lowercase and a GitHub owner need not be, so
|
|
93
|
+
# `github.repository` cannot be used as an image name directly. The build
|
|
94
|
+
# refused the tag rather than mangling it, which is the right failure and
|
|
95
|
+
# is only useful once somebody folds the case here.
|
|
96
|
+
- name: the image name, lowercased
|
|
97
|
+
id: name
|
|
98
|
+
run: echo "image=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
|
|
99
|
+
|
|
100
|
+
- uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 # v6.7.0
|
|
101
|
+
id: build
|
|
102
|
+
with:
|
|
103
|
+
context: .
|
|
104
|
+
# A bill of materials and a provenance attestation, so somebody who
|
|
105
|
+
# pulled this can ask what is in it and who built it rather than
|
|
106
|
+
# taking the tag's word for it.
|
|
107
|
+
sbom: true
|
|
108
|
+
provenance: mode=max
|
|
109
|
+
# Two architectures, because half of the people running this are on
|
|
110
|
+
# an ARM laptop and the other half are on an x86 server.
|
|
111
|
+
platforms: linux/amd64,linux/arm64
|
|
112
|
+
push: true
|
|
113
|
+
# Four tags: the exact version, the minor line, the major line for
|
|
114
|
+
# somebody who wants fixes without reading release notes, and latest.
|
|
115
|
+
# Written without the leading `v`, because an image tag conventionally
|
|
116
|
+
# carries the version and not the git tag's name for it.
|
|
117
|
+
tags: |
|
|
118
|
+
${{ steps.name.outputs.image }}:${{ needs.plan.outputs.version }}
|
|
119
|
+
${{ steps.name.outputs.image }}:${{ needs.plan.outputs.major }}.${{ needs.plan.outputs.minor }}
|
|
120
|
+
${{ steps.name.outputs.image }}:${{ needs.plan.outputs.major }}
|
|
121
|
+
${{ steps.name.outputs.image }}:latest
|
|
122
|
+
cache-from: type=gha
|
|
123
|
+
cache-to: type=gha,mode=max
|
|
124
|
+
|
|
125
|
+
- name: attest what was built
|
|
126
|
+
uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4
|
|
127
|
+
with:
|
|
128
|
+
subject-name: ${{ steps.name.outputs.image }}
|
|
129
|
+
subject-digest: ${{ steps.build.outputs.digest }}
|
|
130
|
+
push-to-registry: true
|
|
131
|
+
|
|
132
|
+
package:
|
|
133
|
+
needs: [plan]
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
environment: pypi
|
|
136
|
+
permissions:
|
|
137
|
+
# Trusted publishing: PyPI verifies this workflow rather than a token
|
|
138
|
+
# somebody pasted into a secret and then forgot they had.
|
|
139
|
+
id-token: write
|
|
140
|
+
steps:
|
|
141
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
142
|
+
with:
|
|
143
|
+
ref: ${{ needs.plan.outputs.tag }}
|
|
144
|
+
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
|
|
145
|
+
with:
|
|
146
|
+
python-version: "3.12"
|
|
147
|
+
# The interface is built into the wheel, so `pip install blackboardxray`
|
|
148
|
+
# gives an application the client and gives an operator the whole server.
|
|
149
|
+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
150
|
+
with:
|
|
151
|
+
node-version: "24"
|
|
152
|
+
- run: npm ci --prefix ui && npm run build --prefix ui
|
|
153
|
+
- run: uv build
|
|
154
|
+
- name: the interface is in the wheel
|
|
155
|
+
# It is generated and therefore gitignored, and a build backend that
|
|
156
|
+
# skips what version control ignores would ship a server serving a
|
|
157
|
+
# blank page. Checked here rather than discovered by whoever installs.
|
|
158
|
+
run: |
|
|
159
|
+
set -euo pipefail
|
|
160
|
+
wheel=$(ls dist/*.whl)
|
|
161
|
+
unzip -l "$wheel" > /tmp/wheel.txt
|
|
162
|
+
grep -q "server/web/index.html" /tmp/wheel.txt
|
|
163
|
+
echo "the interface is in $wheel"
|
|
164
|
+
# The twine this bundles has to understand the metadata hatchling writes.
|
|
165
|
+
# v1.12.2 shipped one that predates Metadata-Version 2.5 and reported the
|
|
166
|
+
# name as missing from a wheel that plainly has one.
|
|
167
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# What checks that a dependency has not gone bad, and that the code has not
|
|
2
|
+
# grown a known-shaped hole. Separate from CI because these are slower, and
|
|
3
|
+
# because a scheduled run catches an advisory published after a merge.
|
|
4
|
+
name: security
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main]
|
|
11
|
+
schedule:
|
|
12
|
+
# Weekly, so an advisory published against an unchanged dependency is found
|
|
13
|
+
# without waiting for somebody to open a pull request.
|
|
14
|
+
- cron: "0 6 * * 1"
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
codeql:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
security-events: write
|
|
24
|
+
contents: read
|
|
25
|
+
strategy:
|
|
26
|
+
fail-fast: false
|
|
27
|
+
matrix:
|
|
28
|
+
language: [python, javascript-typescript, actions]
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
31
|
+
- uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
|
32
|
+
with:
|
|
33
|
+
language: ${{ matrix.language }}
|
|
34
|
+
queries: security-extended
|
|
35
|
+
- uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
|
36
|
+
with:
|
|
37
|
+
category: "/language:${{ matrix.language }}"
|
|
38
|
+
|
|
39
|
+
dependency-review:
|
|
40
|
+
# Only meaningful on a pull request: it compares what a change adds against
|
|
41
|
+
# what was there before.
|
|
42
|
+
if: github.event_name == 'pull_request'
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
46
|
+
- uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0
|
|
47
|
+
with:
|
|
48
|
+
fail-on-severity: high
|
|
49
|
+
# A copyleft licence arriving through a transitive dependency is a
|
|
50
|
+
# thing to decide about deliberately rather than discover later.
|
|
51
|
+
deny-licenses: AGPL-3.0, GPL-2.0, GPL-3.0
|
|
52
|
+
|
|
53
|
+
audit:
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
57
|
+
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
|
|
58
|
+
with:
|
|
59
|
+
python-version: "3.12"
|
|
60
|
+
- name: python dependencies
|
|
61
|
+
run: |
|
|
62
|
+
uv export --frozen --no-dev --no-emit-project \
|
|
63
|
+
--format requirements-txt > /tmp/requirements.txt
|
|
64
|
+
uvx pip-audit --requirement /tmp/requirements.txt --strict
|
|
65
|
+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
66
|
+
with:
|
|
67
|
+
node-version: "24"
|
|
68
|
+
- name: interface dependencies
|
|
69
|
+
working-directory: ui
|
|
70
|
+
# The interface ships as static files, so a vulnerability in a build
|
|
71
|
+
# tool is not a vulnerability in what is served. Production
|
|
72
|
+
# dependencies are the ones that reach a browser.
|
|
73
|
+
run: npm audit --omit=dev --audit-level=high
|
|
74
|
+
|
|
75
|
+
secrets:
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
79
|
+
with:
|
|
80
|
+
fetch-depth: 0
|
|
81
|
+
# The binary rather than the action. The action scans the range between
|
|
82
|
+
# two commits, and on a push that has no base it reports a git error and
|
|
83
|
+
# exits non zero having found nothing, which is a red build that says
|
|
84
|
+
# the opposite of what it means. This scans the whole history, once.
|
|
85
|
+
- name: gitleaks
|
|
86
|
+
env:
|
|
87
|
+
VERSION: "8.21.2"
|
|
88
|
+
run: |
|
|
89
|
+
curl -sSfL \
|
|
90
|
+
"https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" \
|
|
91
|
+
| tar -xz -C /tmp gitleaks
|
|
92
|
+
/tmp/gitleaks git . --redact --verbose --exit-code 1
|