src-auth-perms-sync 0.2.1__tar.gz → 0.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.
- src_auth_perms_sync-0.3.0/.github/CODEOWNERS +1 -0
- src_auth_perms_sync-0.3.0/.github/workflows/ci.yml +17 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/.github/workflows/release.yml +178 -61
- src_auth_perms_sync-0.3.0/.github/workflows/validate.yml +267 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/.gitignore +3 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/AGENTS.md +31 -80
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/PKG-INFO +89 -49
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/README.md +87 -47
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/dev/TODO.md +44 -8
- src_auth_perms_sync-0.3.0/dev/mapping-efficiency.md +175 -0
- src_auth_perms_sync-0.3.0/dev/memory-efficiency-analyze.py +618 -0
- src_auth_perms_sync-0.3.0/dev/memory-efficiency-generate.py +1142 -0
- src_auth_perms_sync-0.3.0/dev/memory-efficiency-monitor-sourcegraph.sh +348 -0
- src_auth_perms_sync-0.3.0/dev/memory-efficiency.md +341 -0
- src_auth_perms_sync-0.3.0/dev/test-end-to-end.py +3042 -0
- src_auth_perms_sync-0.3.0/maps-example.yaml +130 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/pyproject.toml +8 -5
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/renovate.json +12 -0
- src_auth_perms_sync-0.3.0/src/src_auth_perms_sync/__init__.py +11 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/cli.py +340 -201
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/orgs/sync.py +11 -11
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/apply.py +58 -11
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/command.py +121 -56
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/full_set.py +52 -24
- src_auth_perms_sync-0.3.0/src/src_auth_perms_sync/permissions/mapping.py +836 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/maps.py +22 -26
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/queries.py +31 -6
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/restore.py +11 -3
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/snapshot.py +26 -26
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/sourcegraph.py +32 -19
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/types.py +20 -12
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/workflow.py +8 -26
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/backups.py +0 -7
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/queries.py +25 -12
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/site_config.py +1 -1
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/sourcegraph.py +9 -3
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/types.py +7 -0
- src_auth_perms_sync-0.3.0/tests/integration/test_cli_entrypoint.py +76 -0
- src_auth_perms_sync-0.3.0/tests/unit/test_apply.py +102 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/unit/test_backups.py +2 -14
- src_auth_perms_sync-0.3.0/tests/unit/test_cli_config.py +533 -0
- src_auth_perms_sync-0.3.0/tests/unit/test_maps.py +540 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/unit/test_restore.py +5 -4
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/unit/test_snapshot.py +24 -33
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/uv.lock +257 -30
- src_auth_perms_sync-0.2.1/.github/workflows/ci.yml +0 -77
- src_auth_perms_sync-0.2.1/dev/git-worktrees.md +0 -89
- src_auth_perms_sync-0.2.1/dev/test-command-permutations.py +0 -1817
- src_auth_perms_sync-0.2.1/dev/test-plan.md +0 -207
- src_auth_perms_sync-0.2.1/maps-example.yaml +0 -39
- src_auth_perms_sync-0.2.1/src/src_auth_perms_sync/__init__.py +0 -1
- src_auth_perms_sync-0.2.1/src/src_auth_perms_sync/permissions/mapping.py +0 -627
- src_auth_perms_sync-0.2.1/src/src_auth_perms_sync/shared/id_codec.py +0 -67
- src_auth_perms_sync-0.2.1/tests/integration/test_cli_entrypoint.py +0 -20
- src_auth_perms_sync-0.2.1/tests/unit/test_cli_config.py +0 -295
- src_auth_perms_sync-0.2.1/tests/unit/test_id_codec.py +0 -26
- src_auth_perms_sync-0.2.1/tests/unit/test_maps.py +0 -75
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/.env.example +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/.markdownlint-cli2.yaml +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/.python-version +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/LICENSE +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/SECURITY.md +0 -0
- /src_auth_perms_sync-0.2.1/dev/dead-code-audit.md → /src_auth_perms_sync-0.3.0/dev/audit-dead-code.md +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/dev/hooks/pre-commit +0 -0
- /src_auth_perms_sync-0.2.1/dev/python-versions.md → /src_auth_perms_sync-0.3.0/dev/update-python-versions.md +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/__main__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/orgs/__init__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/orgs/command.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/orgs/queries.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/orgs/types.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/permissions/__init__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/__init__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/run_context.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/src/src_auth_perms_sync/shared/saml_groups.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/__init__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/integration/__init__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/unit/__init__.py +0 -0
- {src_auth_perms_sync-0.2.1 → src_auth_perms_sync-0.3.0}/tests/unit/test_saml_groups.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @marcleblanc2
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
pull-requests: read
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
validate:
|
|
16
|
+
name: Validate
|
|
17
|
+
uses: ./.github/workflows/validate.yml
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name: Build
|
|
1
|
+
name: Build release
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
@@ -6,16 +6,17 @@ on:
|
|
|
6
6
|
- "v*"
|
|
7
7
|
workflow_dispatch:
|
|
8
8
|
inputs:
|
|
9
|
-
|
|
10
|
-
description: "
|
|
9
|
+
version:
|
|
10
|
+
description: "Package version to publish, for example 0.1.0 or v0.1.0"
|
|
11
11
|
required: true
|
|
12
12
|
type: string
|
|
13
13
|
|
|
14
14
|
permissions:
|
|
15
|
-
contents:
|
|
15
|
+
contents: read
|
|
16
|
+
pull-requests: read
|
|
16
17
|
|
|
17
18
|
concurrency:
|
|
18
|
-
group: release-${{ github.
|
|
19
|
+
group: release-${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }}
|
|
19
20
|
cancel-in-progress: false
|
|
20
21
|
|
|
21
22
|
defaults:
|
|
@@ -23,13 +24,44 @@ defaults:
|
|
|
23
24
|
shell: bash
|
|
24
25
|
|
|
25
26
|
jobs:
|
|
27
|
+
release_ref:
|
|
28
|
+
name: Resolve release tag
|
|
29
|
+
runs-on: ubuntu-24.04
|
|
30
|
+
outputs:
|
|
31
|
+
tag: ${{ steps.release.outputs.tag }}
|
|
32
|
+
version: ${{ steps.release.outputs.version }}
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Resolve release tag
|
|
36
|
+
id: release
|
|
37
|
+
env:
|
|
38
|
+
RELEASE_INPUT: ${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }}
|
|
39
|
+
run: |
|
|
40
|
+
release_input="${RELEASE_INPUT}"
|
|
41
|
+
if [[ ! "${release_input}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
42
|
+
echo "::error title=Invalid release version::Use MAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH, got '${release_input}'."
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
release_version="${release_input#v}"
|
|
47
|
+
release_tag="v${release_version}"
|
|
48
|
+
echo "tag=${release_tag}" >> "${GITHUB_OUTPUT}"
|
|
49
|
+
echo "version=${release_version}" >> "${GITHUB_OUTPUT}"
|
|
50
|
+
|
|
51
|
+
validate:
|
|
52
|
+
name: Validate
|
|
53
|
+
needs: release_ref
|
|
54
|
+
uses: ./.github/workflows/validate.yml
|
|
55
|
+
with:
|
|
56
|
+
ref: ${{ needs.release_ref.outputs.tag }}
|
|
57
|
+
build-package: false
|
|
58
|
+
|
|
26
59
|
wheelhouse:
|
|
27
60
|
name: ${{ matrix.platform }}-py311 wheelhouse
|
|
61
|
+
needs: release_ref
|
|
28
62
|
runs-on: ${{ matrix.runs_on }}
|
|
29
63
|
strategy:
|
|
30
64
|
fail-fast: false
|
|
31
|
-
# The first matrix leg creates the release; later legs upload more assets.
|
|
32
|
-
max-parallel: 1
|
|
33
65
|
matrix:
|
|
34
66
|
include:
|
|
35
67
|
- platform: linux-x86_64
|
|
@@ -55,23 +87,30 @@ jobs:
|
|
|
55
87
|
with:
|
|
56
88
|
fetch-depth: 0
|
|
57
89
|
persist-credentials: false
|
|
58
|
-
ref: ${{
|
|
90
|
+
ref: ${{ needs.release_ref.outputs.tag }}
|
|
59
91
|
|
|
60
92
|
- name: Set up Python
|
|
61
93
|
uses: actions/setup-python@v6
|
|
62
94
|
with:
|
|
63
95
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
64
|
-
|
|
96
|
+
|
|
97
|
+
- name: Cache uv
|
|
98
|
+
uses: actions/cache@v5
|
|
99
|
+
with:
|
|
100
|
+
path: ~/.cache/uv
|
|
101
|
+
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
102
|
+
restore-keys: |
|
|
103
|
+
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
65
104
|
|
|
66
105
|
- name: Install build tools
|
|
67
|
-
run:
|
|
68
|
-
python -m pip install --upgrade pip
|
|
69
|
-
python -m pip install "uv==${UV_VERSION}"
|
|
106
|
+
run: python -m pip install "uv==${UV_VERSION}"
|
|
70
107
|
|
|
71
108
|
- name: Validate release inputs
|
|
72
109
|
id: release
|
|
110
|
+
env:
|
|
111
|
+
RELEASE_TAG: ${{ needs.release_ref.outputs.tag }}
|
|
73
112
|
run: |
|
|
74
|
-
release_tag="${
|
|
113
|
+
release_tag="${RELEASE_TAG}"
|
|
75
114
|
if [[ ! "${release_tag}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
76
115
|
echo "::error title=Invalid release tag::Use a vMAJOR.MINOR.PATCH tag, got '${release_tag}'."
|
|
77
116
|
exit 1
|
|
@@ -89,21 +128,10 @@ jobs:
|
|
|
89
128
|
exit 1
|
|
90
129
|
fi
|
|
91
130
|
|
|
92
|
-
project_version=$(uv run --frozen python - <<'PY'
|
|
93
|
-
import tomllib
|
|
94
|
-
|
|
95
|
-
with open("pyproject.toml", "rb") as pyproject_file:
|
|
96
|
-
print(tomllib.load(pyproject_file)["project"]["version"])
|
|
97
|
-
PY
|
|
98
|
-
)
|
|
99
|
-
if [[ "v${project_version}" != "${release_tag}" ]]; then
|
|
100
|
-
echo "::error title=Version mismatch::pyproject.toml version '${project_version}' does not match tag '${release_tag}'."
|
|
101
|
-
exit 1
|
|
102
|
-
fi
|
|
103
|
-
|
|
104
131
|
echo "tag=${release_tag}" >> "${GITHUB_OUTPUT}"
|
|
132
|
+
echo "version=${release_tag#v}" >> "${GITHUB_OUTPUT}"
|
|
105
133
|
|
|
106
|
-
- name: Validate
|
|
134
|
+
- name: Validate runner architecture
|
|
107
135
|
run: |
|
|
108
136
|
actual_machine=$(uv run --frozen python - <<'PY'
|
|
109
137
|
import platform
|
|
@@ -116,16 +144,11 @@ jobs:
|
|
|
116
144
|
exit 1
|
|
117
145
|
fi
|
|
118
146
|
|
|
119
|
-
uv lock --check
|
|
120
|
-
uv run --frozen ruff check src/src_auth_perms_sync/
|
|
121
|
-
uv run --frozen ruff format --check src/src_auth_perms_sync/
|
|
122
|
-
uv run --frozen pyright
|
|
123
|
-
uv run --frozen src-auth-perms-sync --help >/tmp/src-auth-perms-sync-help.txt
|
|
124
|
-
|
|
125
147
|
- name: Build wheelhouse tarball
|
|
126
148
|
id: build
|
|
127
149
|
run: |
|
|
128
150
|
release_tag="${{ steps.release.outputs.tag }}"
|
|
151
|
+
release_version="${{ steps.release.outputs.version }}"
|
|
129
152
|
release_dir="build/release/${ASSET_BASENAME}"
|
|
130
153
|
wheelhouse_dir="${release_dir}/wheelhouse"
|
|
131
154
|
dist_dir="build/release/dist"
|
|
@@ -136,32 +159,67 @@ jobs:
|
|
|
136
159
|
|
|
137
160
|
rm -rf build/release
|
|
138
161
|
mkdir -p "${wheelhouse_dir}" "${dist_dir}"
|
|
162
|
+
shopt -s nullglob
|
|
139
163
|
|
|
140
|
-
uv build --wheel --out-dir "${dist_dir}" --no-create-gitignore
|
|
164
|
+
uv build --wheel --sdist --out-dir "${dist_dir}" --no-create-gitignore
|
|
141
165
|
project_wheels=("${dist_dir}"/*.whl)
|
|
142
166
|
if [[ "${#project_wheels[@]}" -ne 1 ]]; then
|
|
143
167
|
echo "::error title=Unexpected wheel count::Expected one project wheel, found ${#project_wheels[@]}."
|
|
144
168
|
exit 1
|
|
145
169
|
fi
|
|
170
|
+
project_source_distributions=("${dist_dir}"/*.tar.gz)
|
|
171
|
+
if [[ "${#project_source_distributions[@]}" -ne 1 ]]; then
|
|
172
|
+
echo "::error title=Unexpected source distribution count::Expected one project source distribution, found ${#project_source_distributions[@]}."
|
|
173
|
+
exit 1
|
|
174
|
+
fi
|
|
146
175
|
project_wheel_path="${project_wheels[0]}"
|
|
147
176
|
project_wheel_name="$(basename "${project_wheel_path}")"
|
|
177
|
+
project_source_distribution_path="${project_source_distributions[0]}"
|
|
178
|
+
project_source_distribution_name="$(basename "${project_source_distribution_path}")"
|
|
179
|
+
case "${project_wheel_name}" in
|
|
180
|
+
src_auth_perms_sync-"${release_version}"-*.whl)
|
|
181
|
+
;;
|
|
182
|
+
*)
|
|
183
|
+
echo "::error title=Wheel version mismatch::Expected wheel version ${release_version}, got '${project_wheel_name}'."
|
|
184
|
+
exit 1
|
|
185
|
+
;;
|
|
186
|
+
esac
|
|
187
|
+
case "${project_source_distribution_name}" in
|
|
188
|
+
src_auth_perms_sync-"${release_version}".tar.gz)
|
|
189
|
+
;;
|
|
190
|
+
*)
|
|
191
|
+
echo "::error title=Source distribution version mismatch::Expected source distribution version ${release_version}, got '${project_source_distribution_name}'."
|
|
192
|
+
exit 1
|
|
193
|
+
;;
|
|
194
|
+
esac
|
|
195
|
+
project_wheel_checksum_path="${project_wheel_path}.sha256"
|
|
196
|
+
project_source_distribution_checksum_path="${project_source_distribution_path}.sha256"
|
|
148
197
|
if [[ ! -f "${project_wheel_path}" ]]; then
|
|
149
198
|
echo "::error title=Missing project wheel::Expected ${project_wheel_path} to exist."
|
|
150
199
|
exit 1
|
|
151
200
|
fi
|
|
152
201
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
--
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
202
|
+
dependency_metadata_dir="$(mktemp -d)"
|
|
203
|
+
git clone --no-hardlinks . "${dependency_metadata_dir}" >/dev/null
|
|
204
|
+
(
|
|
205
|
+
cd "${dependency_metadata_dir}"
|
|
206
|
+
git checkout --detach "${release_tag}" >/dev/null
|
|
207
|
+
mkdir -p "$(dirname "${requirements_file}")"
|
|
208
|
+
uv export \
|
|
209
|
+
--no-sources \
|
|
210
|
+
--no-dev \
|
|
211
|
+
--no-emit-project \
|
|
212
|
+
--no-hashes \
|
|
213
|
+
--no-header \
|
|
214
|
+
--no-annotate \
|
|
215
|
+
--output-file "${requirements_file}"
|
|
216
|
+
)
|
|
161
217
|
|
|
218
|
+
cp "${dependency_metadata_dir}/${requirements_file}" "${requirements_file}"
|
|
162
219
|
cp "${requirements_file}" "${runtime_requirements_file}"
|
|
163
|
-
if grep -
|
|
220
|
+
if grep -Eq '(^-e[[:space:]]|^(\.\.?/)|(^|[[:space:]])file:| @ (\.\.?/|file:))' "${runtime_requirements_file}"; then
|
|
164
221
|
echo "::error title=Unexpected local dependency::Runtime requirements must resolve from PyPI."
|
|
222
|
+
cat "${runtime_requirements_file}"
|
|
165
223
|
exit 1
|
|
166
224
|
fi
|
|
167
225
|
|
|
@@ -197,7 +255,7 @@ jobs:
|
|
|
197
255
|
pip install "https://github.com/sourcegraph/src-auth-perms-sync/releases/download/${release_tag}/${project_wheel_name}"
|
|
198
256
|
EOF
|
|
199
257
|
|
|
200
|
-
(cd "${wheelhouse_dir}" && shasum -a 256
|
|
258
|
+
(cd "${wheelhouse_dir}" && shasum -a 256 ./*.whl > WHEELS.sha256)
|
|
201
259
|
|
|
202
260
|
test -f "${project_wheel_path}"
|
|
203
261
|
test -f "${wheelhouse_dir}"/src_auth_perms_sync-*.whl
|
|
@@ -211,16 +269,28 @@ jobs:
|
|
|
211
269
|
exit 1
|
|
212
270
|
fi
|
|
213
271
|
|
|
272
|
+
(
|
|
273
|
+
cd "$(dirname "${project_wheel_path}")"
|
|
274
|
+
shasum -a 256 "${project_wheel_name}" > "$(basename "${project_wheel_checksum_path}")"
|
|
275
|
+
shasum -a 256 "${project_source_distribution_name}" > "$(basename "${project_source_distribution_checksum_path}")"
|
|
276
|
+
)
|
|
277
|
+
|
|
214
278
|
tar -C "${release_dir}" -czf "${asset_path}" wheelhouse
|
|
215
279
|
(
|
|
216
280
|
cd "$(dirname "${asset_path}")"
|
|
217
281
|
shasum -a 256 "$(basename "${asset_path}")" > "$(basename "${checksum_path}")"
|
|
218
282
|
)
|
|
219
283
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
284
|
+
{
|
|
285
|
+
echo "asset_path=${asset_path}"
|
|
286
|
+
echo "checksum_path=${checksum_path}"
|
|
287
|
+
echo "project_wheel_path=${project_wheel_path}"
|
|
288
|
+
echo "project_wheel_name=${project_wheel_name}"
|
|
289
|
+
echo "project_source_distribution_path=${project_source_distribution_path}"
|
|
290
|
+
echo "project_source_distribution_name=${project_source_distribution_name}"
|
|
291
|
+
echo "project_wheel_checksum_path=${project_wheel_checksum_path}"
|
|
292
|
+
echo "project_source_distribution_checksum_path=${project_source_distribution_checksum_path}"
|
|
293
|
+
} >> "${GITHUB_OUTPUT}"
|
|
224
294
|
|
|
225
295
|
- name: Validate offline install from tarball
|
|
226
296
|
run: |
|
|
@@ -244,6 +314,7 @@ jobs:
|
|
|
244
314
|
run: |
|
|
245
315
|
release_tag="${{ steps.release.outputs.tag }}"
|
|
246
316
|
project_wheel_name="${{ steps.build.outputs.project_wheel_name }}"
|
|
317
|
+
project_source_distribution_name="${{ steps.build.outputs.project_source_distribution_name }}"
|
|
247
318
|
notes_path="build/release/release-notes.md"
|
|
248
319
|
cat > "${notes_path}" <<EOF
|
|
249
320
|
## Customer install
|
|
@@ -273,7 +344,9 @@ jobs:
|
|
|
273
344
|
\`\`\`
|
|
274
345
|
|
|
275
346
|
The tarball includes this project, \`src-py-lib\`, and all runtime wheels.
|
|
276
|
-
Verify the
|
|
347
|
+
Verify the tarball downloads with the matching \`.sha256\` files.
|
|
348
|
+
The GitHub release also includes the same \`${project_wheel_name}\` and
|
|
349
|
+
\`${project_source_distribution_name}\` files uploaded to PyPI, plus matching checksums.
|
|
277
350
|
|
|
278
351
|
### Connected PyPI install
|
|
279
352
|
|
|
@@ -296,29 +369,72 @@ jobs:
|
|
|
296
369
|
path: |
|
|
297
370
|
${{ steps.build.outputs.asset_path }}
|
|
298
371
|
${{ steps.build.outputs.checksum_path }}
|
|
372
|
+
|
|
373
|
+
- name: Upload project distribution release artifact
|
|
374
|
+
if: matrix.platform == 'linux-x86_64'
|
|
375
|
+
uses: actions/upload-artifact@v7
|
|
376
|
+
with:
|
|
377
|
+
name: src-auth-perms-sync-project-distributions
|
|
378
|
+
path: |
|
|
299
379
|
${{ steps.build.outputs.project_wheel_path }}
|
|
300
|
-
${{ steps.
|
|
380
|
+
${{ steps.build.outputs.project_source_distribution_path }}
|
|
381
|
+
${{ steps.build.outputs.project_wheel_checksum_path }}
|
|
382
|
+
${{ steps.build.outputs.project_source_distribution_checksum_path }}
|
|
383
|
+
|
|
384
|
+
- name: Upload release notes artifact
|
|
385
|
+
if: matrix.platform == 'linux-x86_64'
|
|
386
|
+
uses: actions/upload-artifact@v7
|
|
387
|
+
with:
|
|
388
|
+
name: release-notes
|
|
389
|
+
path: ${{ steps.notes.outputs.path }}
|
|
301
390
|
|
|
302
391
|
- name: Upload PyPI artifact
|
|
303
392
|
if: matrix.platform == 'linux-x86_64'
|
|
304
393
|
uses: actions/upload-artifact@v7
|
|
305
394
|
with:
|
|
306
395
|
name: pypi-distributions
|
|
307
|
-
path:
|
|
396
|
+
path: |
|
|
397
|
+
${{ steps.build.outputs.project_wheel_path }}
|
|
398
|
+
${{ steps.build.outputs.project_source_distribution_path }}
|
|
399
|
+
|
|
400
|
+
github-release:
|
|
401
|
+
name: Publish GitHub release assets
|
|
402
|
+
needs: [release_ref, validate, wheelhouse]
|
|
403
|
+
runs-on: ubuntu-24.04
|
|
404
|
+
permissions:
|
|
405
|
+
contents: write
|
|
406
|
+
|
|
407
|
+
steps:
|
|
408
|
+
- name: Download wheelhouse artifacts
|
|
409
|
+
uses: actions/download-artifact@v8
|
|
410
|
+
with:
|
|
411
|
+
pattern: src-auth-perms-sync-*
|
|
412
|
+
path: release-assets
|
|
413
|
+
merge-multiple: true
|
|
414
|
+
|
|
415
|
+
- name: Download release notes
|
|
416
|
+
uses: actions/download-artifact@v8
|
|
417
|
+
with:
|
|
418
|
+
name: release-notes
|
|
419
|
+
path: release-notes
|
|
308
420
|
|
|
309
421
|
- name: Publish GitHub release assets
|
|
310
422
|
env:
|
|
311
423
|
GH_TOKEN: ${{ github.token }}
|
|
424
|
+
GH_REPO: ${{ github.repository }}
|
|
425
|
+
RELEASE_TAG: ${{ needs.release_ref.outputs.tag }}
|
|
312
426
|
run: |
|
|
313
|
-
release_tag="${
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
427
|
+
release_tag="${RELEASE_TAG}"
|
|
428
|
+
notes_path="$(find release-notes -name release-notes.md -print -quit)"
|
|
429
|
+
mapfile -t release_assets < <(find release-assets -type f | sort)
|
|
430
|
+
|
|
431
|
+
if [[ -z "${notes_path}" ]]; then
|
|
432
|
+
echo "::error title=Missing release notes::release-notes.md was not found in release artifact."
|
|
433
|
+
exit 1
|
|
434
|
+
fi
|
|
435
|
+
if [[ "${#release_assets[@]}" -eq 0 ]]; then
|
|
436
|
+
echo "::error title=Missing release assets::No release assets were downloaded."
|
|
437
|
+
exit 1
|
|
322
438
|
fi
|
|
323
439
|
|
|
324
440
|
if gh release view "${release_tag}" >/dev/null 2>&1; then
|
|
@@ -334,7 +450,7 @@ jobs:
|
|
|
334
450
|
|
|
335
451
|
pypi:
|
|
336
452
|
name: Publish PyPI package
|
|
337
|
-
needs: wheelhouse
|
|
453
|
+
needs: [validate, wheelhouse]
|
|
338
454
|
runs-on: ubuntu-24.04
|
|
339
455
|
permissions:
|
|
340
456
|
contents: read
|
|
@@ -345,7 +461,7 @@ jobs:
|
|
|
345
461
|
|
|
346
462
|
steps:
|
|
347
463
|
- name: Download built distribution
|
|
348
|
-
uses: actions/download-artifact@
|
|
464
|
+
uses: actions/download-artifact@v8
|
|
349
465
|
with:
|
|
350
466
|
name: pypi-distributions
|
|
351
467
|
path: dist
|
|
@@ -354,3 +470,4 @@ jobs:
|
|
|
354
470
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
355
471
|
with:
|
|
356
472
|
packages-dir: dist
|
|
473
|
+
skip-existing: true
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
name: Validate
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
ref:
|
|
7
|
+
description: "Git ref to validate. Defaults to the caller's ref."
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
build-package:
|
|
11
|
+
description: "Build and smoke-test package artifacts. Release builds do this separately."
|
|
12
|
+
required: false
|
|
13
|
+
type: boolean
|
|
14
|
+
default: true
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
pull-requests: read
|
|
19
|
+
|
|
20
|
+
defaults:
|
|
21
|
+
run:
|
|
22
|
+
shell: bash
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
changes:
|
|
26
|
+
name: Detect changed paths
|
|
27
|
+
runs-on: ubuntu-24.04
|
|
28
|
+
outputs:
|
|
29
|
+
github_actions: ${{ steps.changed_paths.outputs.github_actions }}
|
|
30
|
+
markdown: ${{ steps.changed_paths.outputs.markdown }}
|
|
31
|
+
python: ${{ steps.changed_paths.outputs.python }}
|
|
32
|
+
package: ${{ steps.changed_paths.outputs.package }}
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Detect changed paths
|
|
36
|
+
id: changed_paths
|
|
37
|
+
env:
|
|
38
|
+
GH_TOKEN: ${{ github.token }}
|
|
39
|
+
PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
|
|
40
|
+
run: |
|
|
41
|
+
github_actions_changed=false
|
|
42
|
+
markdown_changed=false
|
|
43
|
+
python_changed=false
|
|
44
|
+
package_changed=false
|
|
45
|
+
|
|
46
|
+
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
|
|
47
|
+
github_actions_changed=true
|
|
48
|
+
markdown_changed=true
|
|
49
|
+
python_changed=true
|
|
50
|
+
package_changed=true
|
|
51
|
+
else
|
|
52
|
+
changed_files="$(mktemp)"
|
|
53
|
+
gh api --paginate \
|
|
54
|
+
"repos/${GITHUB_REPOSITORY}/pulls/${PULL_REQUEST_NUMBER}/files" \
|
|
55
|
+
--jq '.[].filename' > "${changed_files}"
|
|
56
|
+
|
|
57
|
+
while IFS= read -r changed_file; do
|
|
58
|
+
case "${changed_file}" in
|
|
59
|
+
.github/workflows/*)
|
|
60
|
+
github_actions_changed=true
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
|
|
64
|
+
case "${changed_file}" in
|
|
65
|
+
*.md|.markdownlint-cli2.yaml)
|
|
66
|
+
markdown_changed=true
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
|
|
70
|
+
case "${changed_file}" in
|
|
71
|
+
.python-version|pyproject.toml|uv.lock|dev/*|src/*|tests/*)
|
|
72
|
+
python_changed=true
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
|
|
76
|
+
case "${changed_file}" in
|
|
77
|
+
.python-version|LICENSE|README.md|maps-example.yaml|pyproject.toml|uv.lock|src/*)
|
|
78
|
+
package_changed=true
|
|
79
|
+
;;
|
|
80
|
+
esac
|
|
81
|
+
done < "${changed_files}"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
{
|
|
85
|
+
echo "github_actions=${github_actions_changed}"
|
|
86
|
+
echo "markdown=${markdown_changed}"
|
|
87
|
+
echo "python=${python_changed}"
|
|
88
|
+
echo "package=${package_changed}"
|
|
89
|
+
} >> "${GITHUB_OUTPUT}"
|
|
90
|
+
|
|
91
|
+
github_actions:
|
|
92
|
+
name: Lint GitHub Actions
|
|
93
|
+
needs: changes
|
|
94
|
+
if: needs.changes.outputs.github_actions == 'true'
|
|
95
|
+
runs-on: ubuntu-24.04
|
|
96
|
+
env:
|
|
97
|
+
ACTIONLINT_VERSION: "1.7.12"
|
|
98
|
+
|
|
99
|
+
steps:
|
|
100
|
+
- name: Check out code
|
|
101
|
+
uses: actions/checkout@v6
|
|
102
|
+
with:
|
|
103
|
+
persist-credentials: false
|
|
104
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
105
|
+
|
|
106
|
+
- name: Install actionlint
|
|
107
|
+
run: |
|
|
108
|
+
mkdir -p "${HOME}/.local/bin"
|
|
109
|
+
asset="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
|
|
110
|
+
checksums="actionlint_${ACTIONLINT_VERSION}_checksums.txt"
|
|
111
|
+
base_url="https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}"
|
|
112
|
+
|
|
113
|
+
curl -fsSLO "${base_url}/${asset}"
|
|
114
|
+
curl -fsSLO "${base_url}/${checksums}"
|
|
115
|
+
grep " ${asset}$" "${checksums}" | sha256sum --check
|
|
116
|
+
tar -xzf "${asset}" -C "${HOME}/.local/bin" actionlint
|
|
117
|
+
chmod 0755 "${HOME}/.local/bin/actionlint"
|
|
118
|
+
|
|
119
|
+
- name: Lint GitHub Actions
|
|
120
|
+
run: |
|
|
121
|
+
"${HOME}/.local/bin/actionlint"
|
|
122
|
+
|
|
123
|
+
markdown:
|
|
124
|
+
name: Lint Markdown
|
|
125
|
+
needs: changes
|
|
126
|
+
if: needs.changes.outputs.markdown == 'true'
|
|
127
|
+
runs-on: ubuntu-24.04
|
|
128
|
+
env:
|
|
129
|
+
MARKDOWNLINT_CLI2_VERSION: "0.22.1"
|
|
130
|
+
|
|
131
|
+
steps:
|
|
132
|
+
- name: Check out code
|
|
133
|
+
uses: actions/checkout@v6
|
|
134
|
+
with:
|
|
135
|
+
persist-credentials: false
|
|
136
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
137
|
+
|
|
138
|
+
- name: Cache npm
|
|
139
|
+
uses: actions/cache@v5
|
|
140
|
+
with:
|
|
141
|
+
path: ~/.npm
|
|
142
|
+
key: npm-${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}
|
|
143
|
+
|
|
144
|
+
- name: Lint Markdown
|
|
145
|
+
run: npx --yes "markdownlint-cli2@${MARKDOWNLINT_CLI2_VERSION}"
|
|
146
|
+
|
|
147
|
+
python:
|
|
148
|
+
name: Validate Python
|
|
149
|
+
needs: changes
|
|
150
|
+
if: needs.changes.outputs.python == 'true'
|
|
151
|
+
runs-on: ubuntu-24.04
|
|
152
|
+
env:
|
|
153
|
+
PYTHON_VERSION: "3.11"
|
|
154
|
+
UV_VERSION: "0.11.7"
|
|
155
|
+
|
|
156
|
+
steps:
|
|
157
|
+
- name: Check out code
|
|
158
|
+
uses: actions/checkout@v6
|
|
159
|
+
with:
|
|
160
|
+
fetch-depth: 0
|
|
161
|
+
persist-credentials: false
|
|
162
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
163
|
+
|
|
164
|
+
- name: Set up Python
|
|
165
|
+
uses: actions/setup-python@v6
|
|
166
|
+
with:
|
|
167
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
168
|
+
|
|
169
|
+
- name: Cache uv
|
|
170
|
+
uses: actions/cache@v5
|
|
171
|
+
with:
|
|
172
|
+
path: ~/.cache/uv
|
|
173
|
+
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
174
|
+
restore-keys: |
|
|
175
|
+
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
176
|
+
|
|
177
|
+
- name: Install uv
|
|
178
|
+
run: python -m pip install "uv==${UV_VERSION}"
|
|
179
|
+
|
|
180
|
+
- name: Validate lockfile
|
|
181
|
+
run: uv lock --check
|
|
182
|
+
|
|
183
|
+
- name: Lint Python
|
|
184
|
+
run: uv run --frozen ruff check .
|
|
185
|
+
|
|
186
|
+
- name: Check Python formatting
|
|
187
|
+
run: uv run --frozen ruff format --check .
|
|
188
|
+
|
|
189
|
+
- name: Type check
|
|
190
|
+
run: uv run --frozen pyright
|
|
191
|
+
|
|
192
|
+
- name: Run tests
|
|
193
|
+
run: uv run --frozen python -m unittest discover -s tests
|
|
194
|
+
|
|
195
|
+
- name: Smoke test source checkout CLI
|
|
196
|
+
run: uv run --frozen src-auth-perms-sync --help >/tmp/src-auth-perms-sync-help.txt
|
|
197
|
+
|
|
198
|
+
package_build:
|
|
199
|
+
name: Build and smoke-test package
|
|
200
|
+
needs: changes
|
|
201
|
+
if: inputs.build-package && needs.changes.outputs.package == 'true'
|
|
202
|
+
runs-on: ubuntu-24.04
|
|
203
|
+
env:
|
|
204
|
+
PACKAGE_NAME: src-auth-perms-sync
|
|
205
|
+
PYTHON_VERSION: "3.11"
|
|
206
|
+
UV_VERSION: "0.11.7"
|
|
207
|
+
|
|
208
|
+
steps:
|
|
209
|
+
- name: Check out code
|
|
210
|
+
uses: actions/checkout@v6
|
|
211
|
+
with:
|
|
212
|
+
fetch-depth: 0
|
|
213
|
+
persist-credentials: false
|
|
214
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
215
|
+
|
|
216
|
+
- name: Set up Python
|
|
217
|
+
uses: actions/setup-python@v6
|
|
218
|
+
with:
|
|
219
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
220
|
+
|
|
221
|
+
- name: Cache uv
|
|
222
|
+
uses: actions/cache@v5
|
|
223
|
+
with:
|
|
224
|
+
path: ~/.cache/uv
|
|
225
|
+
key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('uv.lock') }}
|
|
226
|
+
restore-keys: |
|
|
227
|
+
uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
|
|
228
|
+
|
|
229
|
+
- name: Install uv
|
|
230
|
+
run: python -m pip install "uv==${UV_VERSION}"
|
|
231
|
+
|
|
232
|
+
- name: Build distributions
|
|
233
|
+
run: uv build --wheel --sdist --out-dir dist --no-create-gitignore
|
|
234
|
+
|
|
235
|
+
- name: Smoke test installed wheel
|
|
236
|
+
run: |
|
|
237
|
+
python -m venv build/ci-venv
|
|
238
|
+
. build/ci-venv/bin/activate
|
|
239
|
+
python -m pip install dist/src_auth_perms_sync-*.whl
|
|
240
|
+
src-auth-perms-sync --help >/tmp/src-auth-perms-sync-installed-help.txt
|
|
241
|
+
python -m src_auth_perms_sync --help >/tmp/src-auth-perms-sync-module-help.txt
|
|
242
|
+
|
|
243
|
+
package:
|
|
244
|
+
name: Validate package
|
|
245
|
+
needs: [changes, github_actions, markdown, python, package_build]
|
|
246
|
+
if: always()
|
|
247
|
+
runs-on: ubuntu-24.04
|
|
248
|
+
|
|
249
|
+
steps:
|
|
250
|
+
- name: Confirm validation results
|
|
251
|
+
run: |
|
|
252
|
+
for validation_result in \
|
|
253
|
+
"${{ needs.changes.result }}" \
|
|
254
|
+
"${{ needs.github_actions.result }}" \
|
|
255
|
+
"${{ needs.markdown.result }}" \
|
|
256
|
+
"${{ needs.python.result }}" \
|
|
257
|
+
"${{ needs.package_build.result }}"
|
|
258
|
+
do
|
|
259
|
+
case "${validation_result}" in
|
|
260
|
+
success|skipped)
|
|
261
|
+
;;
|
|
262
|
+
*)
|
|
263
|
+
echo "::error title=Validation failed::At least one validation job ended with '${validation_result}'."
|
|
264
|
+
exit 1
|
|
265
|
+
;;
|
|
266
|
+
esac
|
|
267
|
+
done
|