tag-publish 0.0.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.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2020-2026, Camptocamp SA
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,394 @@
1
+ Metadata-Version: 2.4
2
+ Name: tag-publish
3
+ Version: 0.0.0
4
+ Summary: Tools used to publish Python packages, Docker images and Helm charts for GitHub tag and branch
5
+ License: FreeBSD
6
+ License-File: LICENSE
7
+ Keywords: ci
8
+ Author: Camptocamp
9
+ Author-email: info@camptocamp.com
10
+ Requires-Python: >=3.10
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Typing :: Typed
23
+ Requires-Dist: PyYAML (>=6,<7)
24
+ Requires-Dist: applications-download (>=1,<2)
25
+ Requires-Dist: debian-inspector (>=31,<32)
26
+ Requires-Dist: githubkit (>=0,<1)
27
+ Requires-Dist: id (>=1,<2)
28
+ Requires-Dist: jsonschema-validator-new (>=0,<1)
29
+ Requires-Dist: multi-repo-automation (>=1,<2)
30
+ Requires-Dist: requests (>=2,<3)
31
+ Requires-Dist: security-md (>=1,<2)
32
+ Requires-Dist: twine (>=6,<7)
33
+ Project-URL: Bug Tracker, https://github.com/camptocamp/tag-publish/issues
34
+ Project-URL: Repository, https://github.com/camptocamp/tag-publish
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Tag Publish
38
+
39
+ ## Publishing
40
+
41
+ The main goals of Tag Publish offer the commands to publish the project,
42
+ Using a tag, a stabilization branch, a feature branch or a pull request.
43
+
44
+ When possible it can do a secret-less publishing (privileged in defaults), if it's not possible the login should be done before the publishing.
45
+
46
+ See the [documentation](https://github.com/camptocamp/c2cciutils/wiki/Publishing).
47
+
48
+ ## Startup
49
+
50
+ Set the permissions:
51
+
52
+ ```yaml
53
+ permissions:
54
+ # To publish Docker images on GHCR, npm packages and Helm charts on OCI registry
55
+ packages: write
56
+ # To publish Python packages using OIDC and for cosign keyless signing
57
+ id-token: write
58
+ # To publish Helm charts (chart-releaser) and send repository dispatch notifications
59
+ contents: write
60
+ ```
61
+
62
+ Install the package in the worklow:
63
+
64
+ ```yaml
65
+ - name: Install tag-publish
66
+ run: pip install tag-publish
67
+ ```
68
+
69
+ Do the publishing:
70
+
71
+ ```yaml
72
+ - name: Publish
73
+ run: tag-publish
74
+ env:
75
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76
+ ```
77
+
78
+ ## New version
79
+
80
+ To create a new version you should create a Git tag with the version number.
81
+
82
+ ## New stabilization branch
83
+
84
+ To create a new minor version you just should run `tag-publish-new --version=<version>`.
85
+
86
+ This will create the stabilization branch and will create a new pull request to update
87
+ the `SECURITY.md` file and the Renovate configuration.
88
+
89
+ This will also create the tags for the backport.
90
+
91
+ You are welcome to run `tag-publish-new --help` to see what's it's done.
92
+
93
+ Note that it didn't create a tag, you should do it manually.
94
+
95
+ To create a patch version you should just create tag.
96
+
97
+ ## Kind of publishing
98
+
99
+ This tool can publish on different kind of versions:
100
+
101
+ - `tag`: Related to a Git tag.
102
+ - `default_branch`: Related to the default branch.
103
+ - `stabilization_branch`: Related to a stabilization branch (including the default branch).
104
+ - `feature_branch`: Related to a feature branch or a pull request.
105
+
106
+ We can also publish on different kind of versions like `rebuild` by using the `--type` argument.
107
+
108
+ ## SECURITY.md
109
+
110
+ The `SECURITY.md` file should contain the security policy of the repository, especially the end of
111
+ support dates.
112
+
113
+ For compatibility with [`security.md`](https://github.com/sbrunner/security.md/) it should contain an array
114
+ with at least the columns `Version` and `Supported Until`. The `Version` column will contain the concerned
115
+ version.
116
+ The `Supported Until` will contain the date of end of support `dd/mm/yyyy`.
117
+ It can also contain the following sentences:
118
+
119
+ - `Unsupported`: no longer supported => no audit, no rebuild.
120
+ - `Best effort`: the support is ended, it is still rebuilt and audited, but this can be stopped without any notice.
121
+ - `To be defined`: not yet released or the date will be set related of another project release date (like for GeoMapFish).
122
+
123
+ See also [GitHub Documentation](https://docs.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)
124
+
125
+ ## Configuration
126
+
127
+ The configuration file is `.github/publish.yaml`, the schema is `https://raw.githubusercontent.com/camptocamp/tag-publish/<version>/tag_publish/schema.json`.
128
+
129
+ ### Dry run
130
+
131
+ Dry run publish: `GITHUB_REF=... tag-publish --dry-run ...`
132
+
133
+ ### Python package to pypi repository
134
+
135
+ Minimum configuration:
136
+
137
+ ```yaml
138
+ pypi:
139
+ packages:
140
+ - {}
141
+ ```
142
+
143
+ If the file `~/.pypirc` didn't exists we will do a login using OpenId Connect (OIDC), see:
144
+ https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-pypi.
145
+
146
+ By default the package will be published only on tag, if you want to publish on stabilization branch you should add
147
+ a `versions` key with the list of versions you want to publish, that can be:
148
+ `rebuild` (specified with --type), `tag`, `default_branch`, `stabilization_branch`, `feature_branch`, `pull_request` (for pull request merge: number)
149
+
150
+ It we have a `setup.py` file, we will be in legacy mode:
151
+ When publishing, the version computed from arguments or `GITHUB_REF` is put in environment variable `VERSION`, thus you should use it in `setup.py`, example:
152
+
153
+ ```python
154
+ VERSION = os.environ.get("VERSION", "1.0.0")
155
+ ```
156
+
157
+ Also we consider that we use `poetry` with [poetry-dynamic-versioning](https://pypi.org/project/poetry-dynamic-versioning/) to manage the version, and [poetry-plugin-tweak-dependencies-version](https://pypi.org/project/poetry-plugin-tweak-dependencies-version/) to manage the dependencies versions.
158
+
159
+ Example of configuration:
160
+
161
+ ```toml
162
+ [tool.poetry-dynamic-versioning]
163
+ enable = true
164
+ vcs = "git"
165
+ pattern = "^(?P<base>\\d+(\\.\\d+)*)"
166
+ format-jinja = """
167
+ {%- if env.get("VERSION_TYPE") == "default_branch" -%}
168
+ {{serialize_pep440(bump_version(base, 1), dev=distance)}}
169
+ {%- elif env.get("VERSION_TYPE") == "stabilization_branch" -%}
170
+ {{serialize_pep440(bump_version(base, 2), dev=distance)}}
171
+ {%- elif distance == 0 -%}
172
+ {{serialize_pep440(base)}}
173
+ {%- else -%}
174
+ {{serialize_pep440(bump_version(base), dev=distance)}}
175
+ {%- endif -%}
176
+ """
177
+
178
+ ```
179
+
180
+ Note that we can access to the environment variables `VERSION`,`VERSION_TYPE`.
181
+
182
+ Then by default:
183
+
184
+ - Tag with `1.2.3` => release `1.2.3`
185
+ - Commit on feature branch just do a validation
186
+ - Commit on `master` branch after the tag 1.3.0 => release `1.4.0.dev1`
187
+ - Commit on `1.3` branch after the tag 1.3.0 => release `1.3.1.dev1`
188
+
189
+ #### Authentication
190
+
191
+ If the file `~/.pypirc` exists we consider that we ar already logged in also
192
+ we will do the login with the `pypi` server with OpenID Connect (OIDC).
193
+
194
+ The OIDC login is recommended because it didn't needs any additional secrets,
195
+ but it need some configuration on pypi in the package,
196
+ see the [GitHub Documentation](https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-pypi#adding-the-identity-provider-to-pypi).
197
+
198
+ The required permissions is `id-token: write`.
199
+
200
+ #### Integration if the package directly in a Docker image
201
+
202
+ To make it working in the `Dockerfile` you should have in the `poetry` stage:
203
+
204
+ ```Dockerfile
205
+ ENV POETRY_DYNAMIC_VERSIONING_BYPASS=dev
206
+ RUN poetry export --extras=checks --extras=publish --output=requirements.txt \
207
+ && poetry export --with=dev --output=requirements-dev.txt
208
+ ```
209
+
210
+ And in the `run` stage
211
+
212
+ ```Dockerfile
213
+ ARG VERSION=dev
214
+ RUN --mount=type=cache,target=/root/.cache \
215
+ POETRY_DYNAMIC_VERSIONING_BYPASS=${VERSION} python3 -m pip install --disable-pip-version-check --no-deps --editable=.
216
+ ```
217
+
218
+ And in the `Makefile`:
219
+
220
+ ```Makefile
221
+ VERSION = $(strip $(shell poetry version --short))
222
+
223
+ .PHONY: build
224
+ build: ## Build the Docker images
225
+ docker build --build-arg=VERSION=$(VERSION) --tag=$(GITHUB_REPOSITORY) .
226
+ ```
227
+
228
+ ### Docker image to registry
229
+
230
+ The minimal config is like this:
231
+
232
+ ```yaml
233
+ docker:
234
+ images:
235
+ - name: camptocamp/tag-publish
236
+ ```
237
+
238
+ If you want to use the GitHub token to be logged in on ghcr you should set `auto_login` to `True`, the
239
+ requires the permissions are `packages: write`.
240
+
241
+ With that the image initially named `camptocamp/tag-publish:latest` will be published on GitHub GHCR and on Docker hub.
242
+
243
+ The full config is like this:
244
+
245
+ ```yaml
246
+ docker:
247
+ github_oidc_login: True
248
+ latest: True
249
+ images:
250
+ - # The base name of the image we want to publish
251
+ name:
252
+ repository:
253
+ <internal_name>:
254
+ # The fqdn name of the server if not Docker hub
255
+ server:
256
+ # List of kinds of versions you want to publish, that can be: rebuild (specified using --type),
257
+ # tag, stabilization_branch, feature_branch, pull_request (for pull request merge: number)
258
+ version:
259
+ # List of tags we want to publish interpreted with `format(version=version)`
260
+ # e.g. if you use `{version}-lite` when you publish the version `1.2.3` the source tag
261
+ # (that should be built by the application build) is `latest-lite`, and it will be published
262
+ # with the tag `1.2.3-lite`.
263
+ tags:
264
+ # If your images are published by different jobs you can separate them in different groups
265
+ # and publish them with `tag-publish --group=<group>`
266
+ group:
267
+ ```
268
+
269
+ By default, the last line of the `SECURITY.md` file will be published (`docker`) with the tag
270
+ `latest`. Set `latest` to `False` to disable it.
271
+
272
+ #### Use Renovate to trigger a new build instead of the legacy rebuild
273
+
274
+ If the `ci/dpkg-versions.yaml` or `.github/dpkg-versions.yaml` file is present, the package list will be updated on publishing.
275
+
276
+ The versions will be updated by [GHCI](https://github.com/camptocamp/github-app-geo-project/) application.
277
+
278
+ ### Node package to npm repository
279
+
280
+ Minimum configuration:
281
+
282
+ ```yaml
283
+ node:
284
+ packages:
285
+ - {}
286
+ ```
287
+
288
+ If the repository server is `npm.pkg.github.com` we will do a login using `GITHUB_TOKEN`.
289
+
290
+ To publish on `npm.pkg.github.com` you requires the permissions are `packages: write`, and the `id-token: write` for the provenance.
291
+
292
+ By default the package will be published only on tag.
293
+
294
+ ### HELM
295
+
296
+ The minimal config is like this:
297
+
298
+ ```yaml
299
+ helm:
300
+ packages:
301
+ - {}
302
+ ```
303
+
304
+ This will publish the `helm` charts in the current folder using [chart releaser](https://github.com/helm/chart-releaser).
305
+
306
+ The artifacts will be attached to a GitHub release, and the `index.yaml` file will be updated in the `gh-pages` branch.
307
+
308
+ The required permission is `contents: write`.
309
+
310
+ Create the required `gh-pages` branch:
311
+
312
+ ```bash
313
+ git checkout --orphan gh-pages
314
+ git reset --hard
315
+ git commit --allow-empty -m "Initialize gh-pages branch"
316
+ git push origin gh-pages
317
+ ```
318
+
319
+ #### OCI registry publishing
320
+
321
+ By default, the Helm chart is also published to an OCI registry (`ghcr.io/<owner>/<repo>`) and signed with [cosign](https://github.com/sigstore/cosign) using keyless signing.
322
+
323
+ The chart is pushed to `ghcr.io/<owner>/<repo>:<version>` automatically.
324
+
325
+ The required permissions are `packages: write` (for pushing to ghcr.io) and `id-token: write` (for cosign keyless signing).
326
+
327
+ To customize the OCI publishing:
328
+
329
+ ```yaml
330
+ helm:
331
+ packages:
332
+ - folder: charts/my-chart
333
+ oci:
334
+ enabled: true # default: true
335
+ registry: ghcr.io # default: ghcr.io
336
+ sign: true # default: true, keyless signing via cosign
337
+ ```
338
+
339
+ To disable OCI publishing:
340
+
341
+ ```yaml
342
+ helm:
343
+ packages:
344
+ - {}
345
+ oci:
346
+ enabled: false
347
+ ```
348
+
349
+ ## Dispatch
350
+
351
+ The minimal config is like this:
352
+
353
+ ```yaml
354
+ dispatch:
355
+ - {}
356
+ ```
357
+
358
+ The required permission is `contents: write`.
359
+
360
+ This will create a repository dispatch of type `published` on own repository with the `content` e.g.:
361
+
362
+ ```json
363
+ {
364
+ "version": "1.2.3",
365
+ "version_type": "tag",
366
+ "repository": "camptocamp/tag-publish",
367
+ "items": [
368
+ {
369
+ "type": "docker",
370
+ "image": "camptocamp/tag-publish",
371
+ "repository": "ghcr.io",
372
+ "tag": "1.2.3"
373
+ },
374
+ {
375
+ "type": "pypi",
376
+ "path": "."
377
+ },
378
+ {
379
+ "type": "helm",
380
+ "path": "."
381
+ }
382
+ ]
383
+ }
384
+ ```
385
+
386
+ ## Contributing
387
+
388
+ Install the pre-commit hooks:
389
+
390
+ ```bash
391
+ pip install pre-commit
392
+ pre-commit install --allow-missing-config
393
+ ```
394
+