studylife-cli 1.9.2__tar.gz → 1.9.4__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.
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/workflows/ci.yml +61 -27
- studylife_cli-1.9.4/.github/workflows/dependabot-auto-merge.yml +22 -0
- studylife_cli-1.9.4/.github/workflows/dependabot-lockfiles.yml +20 -0
- studylife_cli-1.9.4/.github/workflows/dependency-review.yml +27 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/workflows/scorecard.yml +2 -1
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/CHANGELOG.md +14 -0
- studylife_cli-1.9.4/CODE_OF_CONDUCT.md +138 -0
- studylife_cli-1.9.4/CONTRIBUTING.md +65 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/PKG-INFO +1 -1
- studylife_cli-1.9.4/socket.yml +8 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/_version.py +2 -2
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/uv.lock +1 -1
- studylife_cli-1.9.2/.github/workflows/dependabot-auto-merge.yml +0 -77
- studylife_cli-1.9.2/.github/workflows/dependabot-lockfiles.yml +0 -80
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.github/dependabot.yml +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.gitignore +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/.releaserc.json +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/LICENSE +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/README.md +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/SECURITY.md +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/fuzz/fuzz_models_and_callback.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/pyproject.toml +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/__init__.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/cli.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/client.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/credentials.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/login.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/models.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/src/studylife_cli/tui.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/tests/test_cli.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/tests/test_client.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/tests/test_login.py +0 -0
- {studylife_cli-1.9.2 → studylife_cli-1.9.4}/tests/test_tui.py +0 -0
|
@@ -10,6 +10,14 @@ concurrency:
|
|
|
10
10
|
group: ci-${{ github.event.pull_request.number || github.ref }}
|
|
11
11
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
12
12
|
|
|
13
|
+
env:
|
|
14
|
+
# uv must never download an interpreter from python-build-standalone: that is an
|
|
15
|
+
# external fetch on every single run (it started returning 504 Gateway Timeout on
|
|
16
|
+
# 2026-09-14 and turned CI red at random). The runner's tool cache already ships the
|
|
17
|
+
# version below, resolved locally by actions/setup-python - and with downloads off a
|
|
18
|
+
# missing interpreter fails loudly instead of being pulled in over the network.
|
|
19
|
+
UV_PYTHON_DOWNLOADS: never
|
|
20
|
+
|
|
13
21
|
# Least-privilege default for GITHUB_TOKEN (CodeQL actions/missing-workflow-permissions):
|
|
14
22
|
# jobs that need more declare it themselves.
|
|
15
23
|
permissions:
|
|
@@ -18,26 +26,40 @@ permissions:
|
|
|
18
26
|
jobs:
|
|
19
27
|
lint:
|
|
20
28
|
runs-on: ubuntu-latest
|
|
29
|
+
timeout-minutes: 15
|
|
21
30
|
steps:
|
|
31
|
+
- name: Harden Runner
|
|
32
|
+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
33
|
+
with:
|
|
34
|
+
egress-policy: audit
|
|
22
35
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
23
|
-
- uses: astral-sh/setup-uv@
|
|
36
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
24
37
|
with:
|
|
25
38
|
version: "0.5.8"
|
|
26
39
|
cache-suffix: "lint"
|
|
27
|
-
-
|
|
40
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.12"
|
|
28
43
|
- run: uv sync --frozen
|
|
29
44
|
- run: uv run ruff check .
|
|
30
45
|
- run: uv run ruff format --check .
|
|
31
46
|
|
|
32
47
|
test:
|
|
33
48
|
runs-on: ubuntu-latest
|
|
49
|
+
timeout-minutes: 20
|
|
34
50
|
steps:
|
|
51
|
+
- name: Harden Runner
|
|
52
|
+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
53
|
+
with:
|
|
54
|
+
egress-policy: audit
|
|
35
55
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
36
|
-
- uses: astral-sh/setup-uv@
|
|
56
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
37
57
|
with:
|
|
38
58
|
version: "0.5.8"
|
|
39
59
|
cache-suffix: "test"
|
|
40
|
-
-
|
|
60
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
61
|
+
with:
|
|
62
|
+
python-version: "3.12"
|
|
41
63
|
- run: uv sync --frozen
|
|
42
64
|
- run: uv run pytest
|
|
43
65
|
|
|
@@ -50,12 +72,19 @@ jobs:
|
|
|
50
72
|
# fixed budget per run, enough to catch a crash on the next code change.
|
|
51
73
|
fuzz:
|
|
52
74
|
runs-on: ubuntu-latest
|
|
75
|
+
timeout-minutes: 15
|
|
53
76
|
steps:
|
|
77
|
+
- name: Harden Runner
|
|
78
|
+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
79
|
+
with:
|
|
80
|
+
egress-policy: audit
|
|
54
81
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
55
|
-
- uses: astral-sh/setup-uv@
|
|
82
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
56
83
|
with:
|
|
57
84
|
version: "0.5.8"
|
|
58
|
-
-
|
|
85
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
86
|
+
with:
|
|
87
|
+
python-version: "3.12"
|
|
59
88
|
- run: uv sync --frozen --group fuzz
|
|
60
89
|
- run: uv run python fuzz/fuzz_models_and_callback.py -max_total_time=30 -rss_limit_mb=1024
|
|
61
90
|
|
|
@@ -63,11 +92,16 @@ jobs:
|
|
|
63
92
|
needs: [lint, test]
|
|
64
93
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
|
65
94
|
runs-on: ubuntu-latest
|
|
95
|
+
timeout-minutes: 20
|
|
66
96
|
permissions:
|
|
67
97
|
contents: write
|
|
68
98
|
outputs:
|
|
69
99
|
published: ${{ steps.semrel.outputs.new_release_published }}
|
|
70
100
|
steps:
|
|
101
|
+
- name: Harden Runner
|
|
102
|
+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
103
|
+
with:
|
|
104
|
+
egress-policy: audit
|
|
71
105
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
72
106
|
with:
|
|
73
107
|
fetch-depth: 0
|
|
@@ -99,14 +133,10 @@ jobs:
|
|
|
99
133
|
git fetch origin main
|
|
100
134
|
git checkout -B main origin/main
|
|
101
135
|
- id: semrel
|
|
102
|
-
uses:
|
|
136
|
+
uses: lukislp/ci-workflows/.github/actions/semantic-release@045f17628d155f7e56c2f6ebdbd473b31e247112 # v1.6.0
|
|
103
137
|
with:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@semantic-release/changelog@7.0.0
|
|
107
|
-
@semantic-release/git@11.0.1
|
|
108
|
-
env:
|
|
109
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
138
|
+
dry-run: true
|
|
139
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
110
140
|
- name: No release needed for this push
|
|
111
141
|
if: steps.semrel.outputs.new_release_published != 'true'
|
|
112
142
|
run: |
|
|
@@ -116,11 +146,16 @@ jobs:
|
|
|
116
146
|
needs: [get-version]
|
|
117
147
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.get-version.outputs.published == 'true'
|
|
118
148
|
runs-on: ubuntu-latest
|
|
149
|
+
timeout-minutes: 20
|
|
119
150
|
permissions:
|
|
120
151
|
contents: write
|
|
121
152
|
issues: write
|
|
122
153
|
pull-requests: write
|
|
123
154
|
steps:
|
|
155
|
+
- name: Harden Runner
|
|
156
|
+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
157
|
+
with:
|
|
158
|
+
egress-policy: audit
|
|
124
159
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
125
160
|
with:
|
|
126
161
|
fetch-depth: 0
|
|
@@ -148,13 +183,9 @@ jobs:
|
|
|
148
183
|
git remote set-url origin "git@github.com:${{ github.repository }}.git"
|
|
149
184
|
echo "GIT_SSH_COMMAND=ssh -i ~/.ssh/semantic_release -o IdentitiesOnly=yes" >> "$GITHUB_ENV"
|
|
150
185
|
- id: semrel
|
|
151
|
-
uses:
|
|
186
|
+
uses: lukislp/ci-workflows/.github/actions/semantic-release@045f17628d155f7e56c2f6ebdbd473b31e247112 # v1.6.0
|
|
152
187
|
with:
|
|
153
|
-
|
|
154
|
-
@semantic-release/changelog@7.0.0
|
|
155
|
-
@semantic-release/git@11.0.1
|
|
156
|
-
env:
|
|
157
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
188
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
158
189
|
continue-on-error: true
|
|
159
190
|
- if: steps.semrel.outcome == 'failure'
|
|
160
191
|
name: "Diagnose before retrying (expected: an out-of-band push landed since checkout)"
|
|
@@ -169,13 +200,9 @@ jobs:
|
|
|
169
200
|
fi
|
|
170
201
|
git checkout -B main origin/main
|
|
171
202
|
- if: steps.semrel.outcome == 'failure'
|
|
172
|
-
uses:
|
|
203
|
+
uses: lukislp/ci-workflows/.github/actions/semantic-release@045f17628d155f7e56c2f6ebdbd473b31e247112 # v1.6.0
|
|
173
204
|
with:
|
|
174
|
-
|
|
175
|
-
@semantic-release/changelog@7.0.0
|
|
176
|
-
@semantic-release/git@11.0.1
|
|
177
|
-
env:
|
|
178
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
205
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
179
206
|
|
|
180
207
|
# Runs after semantic-release so the checkout below lands on the freshly tagged commit -
|
|
181
208
|
# hatch-vcs then resolves an exact version (e.g. "1.2.0"), not a "*.dev0+g<hash>" one, which
|
|
@@ -184,18 +211,25 @@ jobs:
|
|
|
184
211
|
needs: [get-version, semantic-release]
|
|
185
212
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.get-version.outputs.published == 'true'
|
|
186
213
|
runs-on: ubuntu-latest
|
|
214
|
+
timeout-minutes: 45
|
|
187
215
|
environment: pypi
|
|
188
216
|
permissions:
|
|
189
217
|
id-token: write # trusted publishing (OIDC) - no PyPI token/secret needed
|
|
190
218
|
steps:
|
|
219
|
+
- name: Harden Runner
|
|
220
|
+
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
|
221
|
+
with:
|
|
222
|
+
egress-policy: audit
|
|
191
223
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
192
224
|
with:
|
|
193
225
|
ref: main
|
|
194
226
|
fetch-depth: 0 # full history + tags, so hatch-vcs can find the tag just created
|
|
195
|
-
- uses: astral-sh/setup-uv@
|
|
227
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
196
228
|
with:
|
|
197
229
|
version: "0.5.8"
|
|
198
230
|
cache-suffix: "publish"
|
|
199
|
-
-
|
|
231
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
232
|
+
with:
|
|
233
|
+
python-version: "3.12"
|
|
200
234
|
- run: uv build
|
|
201
235
|
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Dependabot auto-merge
|
|
2
|
+
|
|
3
|
+
# Thin caller of the shared implementation in lukislp/ci-workflows (auto-merge of Dependabot
|
|
4
|
+
# patch/minor updates, update-stale for every PR that is behind the tip) - the triggers stay
|
|
5
|
+
# here because a reusable workflow cannot declare them for the caller. Needs the AUTOMERGE_TOKEN
|
|
6
|
+
# repository secret (fine-grained PAT, contents + pull requests write).
|
|
7
|
+
on:
|
|
8
|
+
pull_request_target:
|
|
9
|
+
types: [opened, synchronize, reopened, auto_merge_enabled]
|
|
10
|
+
schedule:
|
|
11
|
+
- cron: "23 * * * *"
|
|
12
|
+
push:
|
|
13
|
+
branches: [main]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
pull-requests: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
dependabot:
|
|
20
|
+
uses: lukislp/ci-workflows/.github/workflows/dependabot-auto-merge.yml@045f17628d155f7e56c2f6ebdbd473b31e247112 # v1.6.0
|
|
21
|
+
secrets:
|
|
22
|
+
AUTOMERGE_TOKEN: ${{ secrets.AUTOMERGE_TOKEN }}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Dependabot lock files
|
|
2
|
+
|
|
3
|
+
# Thin caller of the shared implementation in lukislp/ci-workflows: regenerates the lock files
|
|
4
|
+
# on Dependabot's own PRs with the CI tool versions and pushes them back onto the PR branch.
|
|
5
|
+
# Plain pull_request on purpose (never pull_request_target); AUTOMERGE_TOKEN is stored as a
|
|
6
|
+
# Dependabot secret, which only Dependabot-triggered runs can read.
|
|
7
|
+
on:
|
|
8
|
+
pull_request:
|
|
9
|
+
types: [opened, synchronize, reopened]
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
lockfiles:
|
|
16
|
+
uses: lukislp/ci-workflows/.github/workflows/dependabot-lockfiles.yml@045f17628d155f7e56c2f6ebdbd473b31e247112 # v1.6.0
|
|
17
|
+
with:
|
|
18
|
+
uv-version: "0.5.8"
|
|
19
|
+
secrets:
|
|
20
|
+
AUTOMERGE_TOKEN: ${{ secrets.AUTOMERGE_TOKEN }}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Dependency review
|
|
2
|
+
|
|
3
|
+
# Thin caller of the shared implementation in lukislp/ci-workflows - the triggers stay here
|
|
4
|
+
# because a reusable workflow cannot declare them for the caller. Compares the base and head
|
|
5
|
+
# dependency graphs of a pull request and fails it when the PR introduces a dependency with a
|
|
6
|
+
# known advisory, which Dependabot alerts would otherwise only report after the merge. The
|
|
7
|
+
# check name in the branch ruleset is "review / dependency-review".
|
|
8
|
+
on:
|
|
9
|
+
pull_request:
|
|
10
|
+
types: [opened, synchronize, reopened]
|
|
11
|
+
|
|
12
|
+
# One run per PR: a newer push cancels the run it supersedes.
|
|
13
|
+
concurrency:
|
|
14
|
+
group: dependency-review-${{ github.event.pull_request.number || github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
review:
|
|
22
|
+
uses: lukislp/ci-workflows/.github/workflows/dependency-review.yml@045f17628d155f7e56c2f6ebdbd473b31e247112 # v1.6.0
|
|
23
|
+
# pull-requests: write is what the summary comment needs; the called workflow keeps
|
|
24
|
+
# contents at read.
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
pull-requests: write
|
|
@@ -16,6 +16,7 @@ permissions: read-all
|
|
|
16
16
|
jobs:
|
|
17
17
|
analysis:
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 15
|
|
19
20
|
permissions:
|
|
20
21
|
security-events: write
|
|
21
22
|
id-token: write
|
|
@@ -28,6 +29,6 @@ jobs:
|
|
|
28
29
|
results_file: results.sarif
|
|
29
30
|
results_format: sarif
|
|
30
31
|
publish_results: true
|
|
31
|
-
- uses: github/codeql-action/upload-sarif@
|
|
32
|
+
- uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0
|
|
32
33
|
with:
|
|
33
34
|
sarif_file: results.sarif
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.9.4](https://github.com/lukislp/studylife-cli/compare/v1.9.3...v1.9.4) (2026-09-20)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **ci:** add Harden Runner in audit mode to every job ([#42](https://github.com/lukislp/studylife-cli/issues/42)) ([be13fec](https://github.com/lukislp/studylife-cli/commit/be13fec38dc3418643f6f5a8b05e288df2ebd34f))
|
|
7
|
+
|
|
8
|
+
## [1.9.3](https://github.com/lukislp/studylife-cli/compare/v1.9.2...v1.9.3) (2026-09-17)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **ci:** bump astral-sh/setup-uv from 10.0.1 to 10.1.0 ([5248a13](https://github.com/lukislp/studylife-cli/commit/5248a133ecbaf6b9a1bb237432dd94e574de174e))
|
|
14
|
+
|
|
1
15
|
## [1.9.2](https://github.com/lukislp/studylife-cli/compare/v1.9.1...v1.9.2) (2026-09-12)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
10
|
+
identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
* Demonstrating empathy and kindness toward other people
|
|
21
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
* Giving and gracefully accepting constructive feedback
|
|
23
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
* Focusing on what is best not just for us as individuals, but for the overall
|
|
26
|
+
community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
* The use of sexualized language or imagery, and sexual attention or advances of
|
|
31
|
+
any kind
|
|
32
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
* Public or private harassment
|
|
34
|
+
* Publishing others' private information, such as a physical or email address,
|
|
35
|
+
without their explicit permission
|
|
36
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
49
|
+
decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
Examples of representing our community include using an official e-mail address,
|
|
56
|
+
posting via an official social media account, or acting as an appointed
|
|
57
|
+
representative at an online or offline event.
|
|
58
|
+
|
|
59
|
+
## Enforcement
|
|
60
|
+
|
|
61
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
|
+
reported to the community leaders responsible for enforcement at
|
|
63
|
+
155678024+lukislp@users.noreply.github.com.
|
|
64
|
+
All complaints will be reviewed and investigated promptly and fairly.
|
|
65
|
+
|
|
66
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
67
|
+
reporter of any incident.
|
|
68
|
+
|
|
69
|
+
## Enforcement Guidelines
|
|
70
|
+
|
|
71
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
72
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
73
|
+
|
|
74
|
+
### 1. Correction
|
|
75
|
+
|
|
76
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
77
|
+
unprofessional or unwelcome in the community.
|
|
78
|
+
|
|
79
|
+
**Consequence**: A private, written warning from community leaders, providing
|
|
80
|
+
clarity around the nature of the violation and an explanation of why the
|
|
81
|
+
behavior was inappropriate. A public apology may be requested.
|
|
82
|
+
|
|
83
|
+
### 2. Warning
|
|
84
|
+
|
|
85
|
+
**Community Impact**: A violation through a single incident or series of
|
|
86
|
+
actions.
|
|
87
|
+
|
|
88
|
+
**Consequence**: A warning with consequences for continued behavior. No
|
|
89
|
+
interaction with the people involved, including unsolicited interaction with
|
|
90
|
+
those enforcing the Code of Conduct, for a specified period of time. This
|
|
91
|
+
includes avoiding interactions in community spaces as well as external channels
|
|
92
|
+
like social media. Violating these terms may lead to a temporary or permanent
|
|
93
|
+
ban.
|
|
94
|
+
|
|
95
|
+
### 3. Temporary Ban
|
|
96
|
+
|
|
97
|
+
**Community Impact**: A serious violation of community standards, including
|
|
98
|
+
sustained inappropriate behavior.
|
|
99
|
+
|
|
100
|
+
**Consequence**: A temporary ban from any sort of interaction or public
|
|
101
|
+
communication with the community for a specified period of time. No public or
|
|
102
|
+
private interaction with the people involved, including unsolicited interaction
|
|
103
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
104
|
+
Violating these terms may lead to a permanent ban.
|
|
105
|
+
|
|
106
|
+
### 4. Permanent Ban
|
|
107
|
+
|
|
108
|
+
**Community Impact**: Demonstrating a pattern of violation of community
|
|
109
|
+
standards, including sustained inappropriate behavior, harassment of an
|
|
110
|
+
individual, or aggression toward or disparagement of classes of individuals.
|
|
111
|
+
|
|
112
|
+
**Consequence**: A permanent ban from any sort of public interaction within the
|
|
113
|
+
community.
|
|
114
|
+
|
|
115
|
+
## Attribution
|
|
116
|
+
|
|
117
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
118
|
+
version 2.1, available at
|
|
119
|
+
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
|
120
|
+
|
|
121
|
+
Community Impact Guidelines were inspired by
|
|
122
|
+
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
|
123
|
+
|
|
124
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
|
125
|
+
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
|
126
|
+
[https://www.contributor-covenant.org/translations][translations].
|
|
127
|
+
|
|
128
|
+
[homepage]: https://www.contributor-covenant.org
|
|
129
|
+
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
|
130
|
+
[Mozilla CoC]: https://github.com/mozilla/diversity
|
|
131
|
+
[FAQ]: https://www.contributor-covenant.org/faq
|
|
132
|
+
[translations]: https://www.contributor-covenant.org/translations
|
|
133
|
+
|
|
134
|
+
## Reporting a security issue
|
|
135
|
+
|
|
136
|
+
This document covers conduct. A security vulnerability in the code is not a
|
|
137
|
+
conduct matter - report it privately through the process described in
|
|
138
|
+
[SECURITY.md](SECURITY.md) instead of opening a public issue.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Contributing to StudyLife CLI
|
|
2
|
+
|
|
3
|
+
Thanks for taking the time. StudyLife CLI is a single-maintainer project, so the process is
|
|
4
|
+
deliberately small - but it is the same for every change, including the maintainer's own.
|
|
5
|
+
|
|
6
|
+
## How changes get in
|
|
7
|
+
|
|
8
|
+
1. Open an issue first for anything bigger than a typo or an obvious bug fix, so the direction can
|
|
9
|
+
be agreed before you spend time on it. Use the templates under `.github/ISSUE_TEMPLATE/`.
|
|
10
|
+
2. Fork the repository (or branch, if you have write access) and make your change on a branch.
|
|
11
|
+
3. Open a pull request against `main`. The pull-request template asks for what changed and why.
|
|
12
|
+
4. `main` is protected: a PR merges only after the test stage of
|
|
13
|
+
[`.github/workflows/ci.yml`](.github/workflows/ci.yml) is green and the branch is up to date
|
|
14
|
+
with `main` (enable auto-merge and it lands on its own once that is the case). Nobody pushes to
|
|
15
|
+
`main` directly, not even the maintainer.
|
|
16
|
+
|
|
17
|
+
## What a pull request needs
|
|
18
|
+
|
|
19
|
+
- **Conventional Commits.** The version and the changelog are generated from the commit messages
|
|
20
|
+
(`feat:` = minor release, `fix:` = patch release, `build:`/`ci:`/`docs:`/`test:` = no release).
|
|
21
|
+
A released version is published to PyPI, so the commit type decides what users get.
|
|
22
|
+
Squash-merge keeps the PR title as the commit message, so give the PR a Conventional Commit
|
|
23
|
+
title.
|
|
24
|
+
- **Green required checks.** `lint`, `test` and `review / dependency-review` are required; a red
|
|
25
|
+
one blocks the merge.
|
|
26
|
+
- **Tests for new functionality.** New features and bug fixes come with tests in `tests/`
|
|
27
|
+
(`test_cli.py`, `test_client.py`, `test_login.py`, `test_tui.py`). A PR that adds behaviour
|
|
28
|
+
without a test is asked to add one.
|
|
29
|
+
- **Lint and formatting.** The `lint` job runs `ruff check .` **and** `ruff format --check .`. Run
|
|
30
|
+
both before pushing; `ruff check` passing does not mean the formatting is clean.
|
|
31
|
+
- **Lockfile.** CI installs with `uv sync --frozen`, so a dependency change means committing the
|
|
32
|
+
updated `uv.lock` alongside `pyproject.toml`.
|
|
33
|
+
- **Command surface.** This is a user-facing CLI. A renamed command, flag or output format is a
|
|
34
|
+
breaking change for anyone scripting against it - call it out in the PR body so the release
|
|
35
|
+
notes carry it.
|
|
36
|
+
|
|
37
|
+
## Running things locally
|
|
38
|
+
|
|
39
|
+
Python 3.12 or newer, with [uv](https://docs.astral.sh/uv/).
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv sync
|
|
43
|
+
uv run pytest
|
|
44
|
+
uv run ruff check .
|
|
45
|
+
uv run ruff format --check .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The fuzz target is Linux-only (`atheris` publishes no Windows wheel):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
uv sync --frozen --group fuzz
|
|
52
|
+
uv run python fuzz/fuzz_models_and_callback.py -max_total_time=30 -rss_limit_mb=1024
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Releases
|
|
56
|
+
|
|
57
|
+
Merging a `feat:` or `fix:` to `main` cuts a release and publishes the built distributions to PyPI
|
|
58
|
+
via trusted publishing. Users install with `pip install studylife-cli` or
|
|
59
|
+
`pipx install studylife-cli`.
|
|
60
|
+
|
|
61
|
+
## Security issues
|
|
62
|
+
|
|
63
|
+
Please do not open a public issue for a vulnerability - use the private reporting path described
|
|
64
|
+
in [SECURITY.md](SECURITY.md). The [Code of Conduct](CODE_OF_CONDUCT.md) applies to every
|
|
65
|
+
interaction in this repository.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: studylife-cli
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.4
|
|
4
4
|
Summary: Command-line client for StudyLife (self-hosted study organizer) - notes, sessions, course goals, and webhooks from your terminal.
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.9.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 9,
|
|
21
|
+
__version__ = version = '1.9.4'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 9, 4)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
name: Dependabot auto-merge
|
|
2
|
-
|
|
3
|
-
# Merges Dependabot patch and minor updates once every required check is green; majors stay
|
|
4
|
-
# manual. Runs on pull_request_target so the base branch's workflow definition and the repo
|
|
5
|
-
# secrets apply (a Dependabot-triggered pull_request run gets neither). Merges with
|
|
6
|
-
# AUTOMERGE_TOKEN, a fine-grained PAT (contents + pull requests: write): a merge performed with
|
|
7
|
-
# GITHUB_TOKEN would never start the release workflow, because GitHub does not run workflows for
|
|
8
|
-
# events caused by GITHUB_TOKEN. Deliberately no checkout - PR code is never executed here.
|
|
9
|
-
on:
|
|
10
|
-
pull_request_target:
|
|
11
|
-
# auto_merge_enabled: a PR that is already behind when someone arms auto-merge would
|
|
12
|
-
# otherwise wait for the next push to be brought up to date.
|
|
13
|
-
types: [opened, synchronize, reopened, auto_merge_enabled]
|
|
14
|
-
# Safety net for a PR armed while behind when nothing else is pushed for a while.
|
|
15
|
-
schedule:
|
|
16
|
-
- cron: "23 * * * *"
|
|
17
|
-
# The default branch requires pull requests to be up to date before they merge (ruleset).
|
|
18
|
-
# Every push to it therefore leaves the open Dependabot PRs "behind"; the update-stale job
|
|
19
|
-
# below brings them back onto the tip so their auto-merge can proceed without a manual rebase.
|
|
20
|
-
push:
|
|
21
|
-
branches: [main]
|
|
22
|
-
|
|
23
|
-
# GITHUB_TOKEN only reads PR metadata; the merge itself runs with AUTOMERGE_TOKEN (above).
|
|
24
|
-
permissions:
|
|
25
|
-
pull-requests: read
|
|
26
|
-
|
|
27
|
-
jobs:
|
|
28
|
-
auto-merge:
|
|
29
|
-
if: github.event_name == 'pull_request_target' && github.event.action != 'auto_merge_enabled' && github.actor == 'dependabot[bot]'
|
|
30
|
-
runs-on: ubuntu-latest
|
|
31
|
-
env:
|
|
32
|
-
HAS_TOKEN: ${{ secrets.AUTOMERGE_TOKEN != '' }}
|
|
33
|
-
steps:
|
|
34
|
-
- id: meta
|
|
35
|
-
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2.5.0
|
|
36
|
-
with:
|
|
37
|
-
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
-
- if: env.HAS_TOKEN == 'true' && (steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor')
|
|
39
|
-
env:
|
|
40
|
-
GH_TOKEN: ${{ secrets.AUTOMERGE_TOKEN }}
|
|
41
|
-
run: gh pr merge --auto --merge "${{ github.event.pull_request.html_url }}"
|
|
42
|
-
- if: env.HAS_TOKEN != 'true'
|
|
43
|
-
run: echo "AUTOMERGE_TOKEN is not set - leaving this PR for a manual merge"
|
|
44
|
-
|
|
45
|
-
update-stale:
|
|
46
|
-
if: github.event_name == 'push' || github.event_name == 'schedule' || github.event.action == 'auto_merge_enabled'
|
|
47
|
-
runs-on: ubuntu-latest
|
|
48
|
-
env:
|
|
49
|
-
HAS_TOKEN: ${{ secrets.AUTOMERGE_TOKEN != '' }}
|
|
50
|
-
steps:
|
|
51
|
-
- if: env.HAS_TOKEN == 'true'
|
|
52
|
-
env:
|
|
53
|
-
GH_TOKEN: ${{ secrets.AUTOMERGE_TOKEN }}
|
|
54
|
-
REPO: ${{ github.repository }}
|
|
55
|
-
# The default branch requires PRs to be up to date before they merge, so every push
|
|
56
|
-
# here leaves the other open PRs "behind". This brings them back onto the tip: every
|
|
57
|
-
# non-draft PR that has auto-merge enabled or was opened by a person (a Dependabot PR
|
|
58
|
-
# left for a manual decision, i.e. a major bump, is not rebuilt on every push - whoever
|
|
59
|
-
# merges it updates it). GitHub computes the merge state lazily after a push, so UNKNOWN
|
|
60
|
-
# is polled for a while; DIRTY (conflicts) cannot be updated automatically.
|
|
61
|
-
run: |
|
|
62
|
-
for n in $(gh pr list --repo "$REPO" --state open --json number --jq '.[].number'); do
|
|
63
|
-
info="$(gh pr view "$n" --repo "$REPO" --json isDraft,author,autoMergeRequest --jq '"\(.isDraft) \(.author.login) \(.autoMergeRequest != null)"')"
|
|
64
|
-
set -- $info
|
|
65
|
-
draft=$1; author=$2; auto=$3
|
|
66
|
-
[ "$draft" = "true" ] && continue
|
|
67
|
-
if [ "$auto" != "true" ] && [ "$author" = "app/dependabot" ]; then continue; fi
|
|
68
|
-
for attempt in 1 2 3 4 5 6; do
|
|
69
|
-
state="$(gh pr view "$n" --repo "$REPO" --json mergeStateStatus --jq .mergeStateStatus)"
|
|
70
|
-
[ "$state" != "UNKNOWN" ] && break
|
|
71
|
-
sleep 10
|
|
72
|
-
done
|
|
73
|
-
echo "#$n ($author, auto-merge=$auto): $state"
|
|
74
|
-
if [ "$state" = "BEHIND" ]; then
|
|
75
|
-
gh api -X PUT "repos/$REPO/pulls/$n/update-branch" >/dev/null && echo " updated onto main" || echo "::warning::could not update #$n"
|
|
76
|
-
fi
|
|
77
|
-
done
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
name: Dependabot lock files
|
|
2
|
-
|
|
3
|
-
# Dependabot regenerates the lock file of the project whose manifest it bumped, but not the
|
|
4
|
-
# lock files of the projects that depend on it (NuGet records a reference's dependencies in
|
|
5
|
-
# the referencing project's packages.lock.json) - and its uv lock output has shipped unparsable
|
|
6
|
-
# files. Locked-mode restores then fail on the PR. This job runs on Dependabot's own PRs,
|
|
7
|
-
# regenerates every lock file with the same tool versions CI uses and pushes the result back
|
|
8
|
-
# onto the PR branch, after which the normal CI run and the auto-merge proceed.
|
|
9
|
-
#
|
|
10
|
-
# Deliberately a plain pull_request run (no pull_request_target): the PR's own restore runs in
|
|
11
|
-
# the untrusted context with a read-only GITHUB_TOKEN, and the only credential involved - the
|
|
12
|
-
# push token - is a Dependabot secret, which GitHub exposes solely to runs Dependabot triggered
|
|
13
|
-
# and only to the single step that pushes. Nothing from the PR ever sees it.
|
|
14
|
-
on:
|
|
15
|
-
pull_request:
|
|
16
|
-
types: [opened, synchronize, reopened]
|
|
17
|
-
|
|
18
|
-
permissions:
|
|
19
|
-
contents: read
|
|
20
|
-
|
|
21
|
-
jobs:
|
|
22
|
-
refresh:
|
|
23
|
-
if: github.actor == 'dependabot[bot]'
|
|
24
|
-
runs-on: ubuntu-latest
|
|
25
|
-
env:
|
|
26
|
-
HAS_TOKEN: ${{ secrets.AUTOMERGE_TOKEN != '' }}
|
|
27
|
-
HEAD_REF: ${{ github.head_ref }}
|
|
28
|
-
steps:
|
|
29
|
-
- if: env.HAS_TOKEN != 'true'
|
|
30
|
-
run: echo "AUTOMERGE_TOKEN is not set as a Dependabot secret - lock files are not refreshed automatically"
|
|
31
|
-
- if: env.HAS_TOKEN == 'true'
|
|
32
|
-
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
33
|
-
with:
|
|
34
|
-
ref: ${{ github.head_ref }}
|
|
35
|
-
# Full history so the base branch's uv.lock is available locally (private repos
|
|
36
|
-
# cannot be fetched anonymously later, and the push token stays out of this step).
|
|
37
|
-
fetch-depth: 0
|
|
38
|
-
persist-credentials: false
|
|
39
|
-
- if: env.HAS_TOKEN == 'true' && hashFiles('**/packages.lock.json') != ''
|
|
40
|
-
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
|
|
41
|
-
with:
|
|
42
|
-
dotnet-version: "10.0.x"
|
|
43
|
-
- if: env.HAS_TOKEN == 'true' && hashFiles('**/packages.lock.json') != ''
|
|
44
|
-
name: Regenerate every packages.lock.json
|
|
45
|
-
run: |
|
|
46
|
-
set -eu
|
|
47
|
-
for lock in $(git ls-files '**/packages.lock.json' 'packages.lock.json'); do
|
|
48
|
-
proj="$(ls "$(dirname "$lock")"/*.csproj | head -1)"
|
|
49
|
-
echo "restoring $proj"
|
|
50
|
-
dotnet restore "$proj" --force-evaluate -p:RestoreLockedMode=false
|
|
51
|
-
done
|
|
52
|
-
- if: env.HAS_TOKEN == 'true' && hashFiles('uv.lock') != ''
|
|
53
|
-
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
54
|
-
with:
|
|
55
|
-
version: "0.5.8"
|
|
56
|
-
- if: env.HAS_TOKEN == 'true' && hashFiles('uv.lock') != ''
|
|
57
|
-
name: Regenerate uv.lock
|
|
58
|
-
env:
|
|
59
|
-
BASE_REF: ${{ github.base_ref }}
|
|
60
|
-
run: |
|
|
61
|
-
# Dependabot's own uv.lock output has been unparsable, and `uv lock` refuses to start
|
|
62
|
-
# from a broken file - so resolve from the base branch's lock plus the PR's pyproject.
|
|
63
|
-
git show "origin/$BASE_REF:uv.lock" > uv.lock
|
|
64
|
-
uv python install 3.12
|
|
65
|
-
uv lock
|
|
66
|
-
- if: env.HAS_TOKEN == 'true'
|
|
67
|
-
name: Push the refreshed lock files back onto the PR
|
|
68
|
-
env:
|
|
69
|
-
PUSH_TOKEN: ${{ secrets.AUTOMERGE_TOKEN }}
|
|
70
|
-
run: |
|
|
71
|
-
# Only tracked files change here (the lock files); untracked build output stays out.
|
|
72
|
-
git add -u
|
|
73
|
-
if git diff --cached --quiet; then
|
|
74
|
-
echo "lock files already consistent"
|
|
75
|
-
exit 0
|
|
76
|
-
fi
|
|
77
|
-
git config user.name "lukislp"
|
|
78
|
-
git config user.email "koerber.lukas@t-online.de"
|
|
79
|
-
git commit -m "chore(deps): refresh the lock files after the Dependabot update"
|
|
80
|
-
git push "https://x-access-token:${PUSH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:refs/heads/${HEAD_REF}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|