-
Notifications
You must be signed in to change notification settings - Fork 0
165 lines (147 loc) · 6.96 KB
/
Copy pathci.yml
File metadata and controls
165 lines (147 loc) · 6.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
name: CI
# Nothing here needs a controller, credentials or secrets: the test suite never
# touches the network, and the demo render uses the synthetic dataset with
# artwork fetching disabled. Do not add a job that talks to a real controller.
on:
push:
branches: [main]
pull_request:
# So a run can be started by hand against any branch, without opening a pull
# request to provoke one. Added after wanting exactly that and finding there
# was no way to do it. Note the GitHub rule that made it useless on the day:
# manual dispatch is only offered for workflows already on the default
# branch, so this does nothing for a branch until it has been merged.
workflow_dispatch:
permissions:
contents: read
pull-requests: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# pyproject claims 3.11 and up. If one of these fails, either the claim
# is wrong or the code is; do not quietly drop the version.
python-version: ["3.11", "3.12", "3.13"]
steps:
# The SonarQube scanner (run on 3.12 below) needs complete history to
# identify new code correctly.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Install Graphviz
# Provides dot, and unflatten for leaf staggering.
run: sudo apt-get update -qq && sudo apt-get install -y -qq graphviz
- name: Install
# Third-party dependencies come from a hashed lock (KAN-191); the local
# package cannot be, since --require-hashes rejects editable/local
# installs outright, so it is a second, unhashed --no-deps install of
# code this repository already owns. Do not execute package build code
# from dependency source distributions.
run: |
pip install --require-hashes -r requirements/ci.txt
pip install --no-deps --only-binary=:all: -e .
- name: Format
run: python -m ruff format --check .
- name: Lint
run: python -m ruff check .
- name: Tests
run: |
if [ "${{ matrix.python-version }}" = "3.12" ]; then
python -m pytest -q --cov=src/unifi_map --cov-report=xml:coverage.xml
else
python -m pytest -q
fi
- name: Analyze with SonarQube Cloud
# Skipped for Dependabot: GitHub keeps Dependabot-triggered runs on a
# separate secret store from ordinary Actions secrets (same reasoning
# as the read-only GITHUB_TOKEN noted in dependabot-auto-merge.yml),
# so SONAR_TOKEN is empty here regardless of what's configured in repo
# settings. Sonar analyses this project's own source, not a
# dependency's, so a version-bump PR has nothing for it to find
# anyway -- unlike the read-only token, this isn't worth granting
# Dependabot secret access to route around.
if: matrix.python-version == '3.12' && github.actor != 'dependabot[bot]'
uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Render the demo dataset
# Exercises the whole pipeline including Graphviz, which the unit tests
# alone do not. builtin icons plus offline keeps it network-free.
run: |
unifi-map --cache-dir examples/demo --out-dir out \
render --icons builtin --offline -f svg drawio dot html --name ci
test -s out/ci.svg
test -s out/ci.drawio
test -s out/ci.dot
test -s out/ci.html
- name: Render the demo dataset obfuscated
run: |
unifi-map --cache-dir examples/demo --out-dir out-ob \
render --obfuscate --icons builtin --offline -f svg --name ci-ob
test -s out-ob/ci-ob.svg
policy:
name: Repository hygiene
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: No snapshots, renders or artwork committed
# A snapshot is a MAC, hostname and IP inventory. The icon font and
# fetched artwork are Ubiquiti's and are never vendored.
run: |
bad=$(git ls-files | grep -E '^(cache|out)/|\.ttf$|\.woff2?$' || true)
if [ -n "$bad" ]; then
echo "::error::these must not be committed:"
echo "$bad"
exit 1
fi
echo "none found"
audit:
name: Dependency advisories
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Check dependencies against the advisory database
# Advisory, not gating. A new CVE in a transitive dependency should
# start a conversation, not block an unrelated pull request from
# somebody who cannot fix it.
#
# This audits requirements/ci.txt (KAN-191), the hashed lock covering
# the dev and svg extras plus pip-audit itself, rather than whatever
# happens to be installed. The previous version installed the project
# into the runner's own environment and audited that, which never
# worked: `unifi-map` is not on PyPI, so pip-audit reported that it
# could not be audited, `--strict` made that a failure, and
# `continue-on-error` swallowed it. A real advisory and a clean tree
# produced the same ignored red for as long as the job existed.
#
# The lock covers dev tooling (pytest, ruff) as well as the svg extra
# now, a wider net than the `.[svg]`-only closure this job used to
# build by hand; that is a deliberate side effect of sharing one lock
# with the check job rather than maintaining two nearly-identical ones.
#
# pip is excluded: it is the venv's own tooling rather than anything
# this project depends on, and an advisory against the runner's
# bundled pip is not actionable here. setuptools and wheel no longer
# need excluding -- neither is a transitive dependency of anything in
# the lock, so they never appear in the freeze in the first place.
continue-on-error: true
run: |
python -m venv /tmp/depsenv
/tmp/depsenv/bin/pip install --quiet --require-hashes -r requirements/ci.txt
/tmp/depsenv/bin/pip freeze | grep -viE '^pip([=@ ]|$)' > /tmp/requirements.txt
echo "Auditing:"
sed 's/^/ /' /tmp/requirements.txt
/tmp/depsenv/bin/pip-audit --strict --progress-spinner off -r /tmp/requirements.txt