-
Notifications
You must be signed in to change notification settings - Fork 2
204 lines (196 loc) · 7 KB
/
Copy pathci.yml
File metadata and controls
204 lines (196 loc) · 7 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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
name: CI
on:
push:
branches:
- master
tags:
- "v*"
pull_request:
branches:
- master
# Cancel in-flight runs when newer commits are pushed to the same
# branch/PR, but never cancel a tag run mid-publish.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }}
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
- name: Install only ruff
run: uv sync --only-group ruff
- name: Lint
run: uv run --no-sync ruff check --output-format=github .
- name: Format
run: uv run --no-sync ruff format --check .
typecheck:
name: Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
# ty needs the runtime dependencies installed to resolve their
# imports, so this installs the project itself, unlike the lint job
- name: Install ty and runtime dependencies
run: uv sync --no-default-groups --group ty
- name: Typecheck
run: uv run --no-sync ty check --output-format=github --error-on-warning
test:
name: Test on ${{ matrix.name }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
# every platform on the latest python, plus a single job on the
# oldest supported one to catch anything newer than it allows
- name: Linux py314
os: ubuntu-latest
pyversion: "3.14"
- name: macOS py314
os: macos-latest
pyversion: "3.14"
- name: Windows py314
os: windows-latest
pyversion: "3.14"
- name: Linux py313
os: ubuntu-latest
pyversion: "3.13"
env:
# the test suite exercises a real OS keyring; this makes it fail
# instead of skipping those tests if the setup below breaks
KEYCMD_REQUIRE_OS_KEYRING: "1"
# the keyrings created below only ever hold test credentials
KEYCMD_KEYRING_PASSWORD: keycmd-test
steps:
- uses: actions/checkout@v7
- name: Install uv and Python ${{ matrix.pyversion }}
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: ${{ matrix.pyversion }}
enable-cache: true
cache-dependency-glob: "pyproject.toml"
cache-suffix: py${{ matrix.pyversion }}
- name: Install dependencies
run: uv sync
# windows runners expose the credential manager to the session out of
# the box; the other two need a keyring that unlocks without a prompt
- name: Install gnome-keyring
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends gnome-keyring dbus-x11
- name: Create a keychain
if: runner.os == 'macOS'
run: |
security create-keychain -p "$KEYCMD_KEYRING_PASSWORD" "$KEYCHAIN"
# no auto lock, neither on a timeout nor on sleep
security set-keychain-settings "$KEYCHAIN"
security unlock-keychain -p "$KEYCMD_KEYRING_PASSWORD" "$KEYCHAIN"
# the keyring package talks to the default keychain
security list-keychains -d user -s "$KEYCHAIN" login.keychain
security default-keychain -s "$KEYCHAIN"
env:
KEYCHAIN: keycmd-test.keychain
# the secret service is bound to a d-bus session, so the tests have to
# run inside one, with the keyring daemon unlocked and running in it
- name: Test in a d-bus session
if: runner.os == 'Linux'
run: |
dbus-run-session -- bash -c '
printf "%s" "$KEYCMD_KEYRING_PASSWORD" |
gnome-keyring-daemon --unlock --components=secrets
uv run --no-sync pytest -v --cov=keycmd --cov-report=term-missing \
--cov-fail-under=95 tests
'
- name: Test
if: runner.os != 'Linux'
run: >
uv run --no-sync pytest -v --cov=keycmd --cov-report=term-missing
--cov-fail-under=95 tests
test-wsl:
name: Test on WSL
runs-on: windows-latest
timeout-minutes: 20
env:
KEYCMD_REQUIRE_OS_KEYRING: "1"
KEYCMD_TEST_WSL: "1"
steps:
- uses: actions/checkout@v7
- name: Install uv and Python 3.14
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: "3.14"
enable-cache: true
cache-dependency-glob: "pyproject.toml"
cache-suffix: py3.14
- name: Install dependencies
run: uv sync
# WSL only provides the shell keycmd is invoked from; keycmd itself
# runs as a windows process, reading the windows credential manager
- name: Install WSL
uses: Vampire/setup-wsl@d1da7f2c0322a5ee4f24975344f67fc0f5baf364 # v7.0.0
with:
# the smallest distribution, on the WSL version that needs no
# virtual machine: the tests only need a shell on the other side
# of the interop boundary, and provisioning WSLv2 with a store
# distribution has taken anywhere from one to twenty minutes
distribution: Alpine-3.23
wsl-version: 1
- name: Test
run: uv run --no-sync pytest -v tests/test_wsl.py
build:
name: Build and test wheel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
- name: Build sdist and wheel
run: uv build
- name: Twine check
run: uvx twine check dist/*
- name: Upload wheel artifact
uses: actions/upload-artifact@v7
with:
path: dist
name: dist
publish:
name: Publish to Github and Pypi
runs-on: ubuntu-latest
needs: [lint, typecheck, test, test-wsl, build]
if: success() && startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- name: Download wheel artifact
uses: actions/download-artifact@v8
with:
name: dist
path: dist
- name: Release to GitHub
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
files: |
dist/*.tar.gz
dist/*.whl
draft: true
prerelease: false
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_PASSWORD }}