c2cciutils 1.7.0.dev277__tar.gz → 1.7.0.dev281__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.
Files changed (42) hide show
  1. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/PKG-INFO +2 -1
  2. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/audit.py +6 -5
  3. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/configuration.py +3 -18
  4. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/schema.json +2 -5
  5. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/main.py +2 -5
  6. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/publish.py +2 -2
  7. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/pyproject.toml +2 -2
  8. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/setup.py +2 -3
  9. c2cciutils-1.7.0.dev277/c2cciutils/security.py +0 -112
  10. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/LICENSE +0 -0
  11. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/README.md +0 -0
  12. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/__init__.py +0 -0
  13. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/applications-versions.yaml +0 -0
  14. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/applications.yaml +0 -0
  15. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/applications_definition.py +0 -0
  16. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/branches.graphql +0 -0
  17. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/commits.graphql +0 -0
  18. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/default_branch.graphql +0 -0
  19. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/env.py +0 -0
  20. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/lib/docker.py +0 -0
  21. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/package-lock.json +0 -0
  22. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/package.json +0 -0
  23. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/pr_checks.py +0 -0
  24. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/publish.py +0 -0
  25. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/schema-applications.json +0 -0
  26. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/__init__.py +0 -0
  27. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/audit.py +0 -0
  28. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/clean.py +0 -0
  29. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/docker_logs.py +0 -0
  30. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/docker_versions_gen.py +0 -0
  31. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/docker_versions_update.py +0 -0
  32. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/download_applications.py +0 -0
  33. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/env.py +0 -0
  34. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/k8s/__init__.py +0 -0
  35. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/k8s/db.py +0 -0
  36. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/k8s/install.py +0 -0
  37. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/k8s/logs.py +0 -0
  38. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/k8s/wait.py +0 -0
  39. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/pin_pipenv.py +0 -0
  40. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/pr_checks.py +0 -0
  41. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/trigger_image_update.py +0 -0
  42. {c2cciutils-1.7.0.dev277 → c2cciutils-1.7.0.dev281}/c2cciutils/scripts/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: c2cciutils
3
- Version: 1.7.0.dev277
3
+ Version: 1.7.0.dev281
4
4
  Summary: Common utilities for Camptocamp CI
5
5
  Home-page: https://github.com/camptocamp/c2cciutils
6
6
  License: FreeBSD
@@ -39,6 +39,7 @@ Requires-Dist: multi-repo-automation (>=1.0.0,<2.0.0) ; extra == "version"
39
39
  Requires-Dist: python-magic (>=0.0.0,<1.0.0)
40
40
  Requires-Dist: requests (>=2.0.0,<3.0.0)
41
41
  Requires-Dist: ruamel.yaml (>=0.0.0,<1.0.0)
42
+ Requires-Dist: security-md (>=0.0.0,<1.0.0)
42
43
  Requires-Dist: toml (>=0.0.0,<1.0.0)
43
44
  Requires-Dist: tomlkit (>=0.0.0,<1.0.0) ; extra == "publish"
44
45
  Requires-Dist: twine (>=5.0.0,<6.0.0) ; extra == "publish"
@@ -9,9 +9,10 @@ import subprocess # nosec
9
9
  import sys
10
10
  from argparse import Namespace
11
11
 
12
+ import security_md
13
+
12
14
  import c2cciutils
13
15
  import c2cciutils.configuration
14
- import c2cciutils.security
15
16
 
16
17
 
17
18
  def print_versions(
@@ -209,7 +210,7 @@ def outdated_versions(
209
210
  return True
210
211
 
211
212
  with open("SECURITY.md", encoding="utf-8") as security_file:
212
- security = c2cciutils.security.Security(security_file.read())
213
+ security = security_md.Security(security_file.read())
213
214
 
214
215
  version_index = security.version_index
215
216
  date_index = security.support_until_index
@@ -217,9 +218,9 @@ def outdated_versions(
217
218
  for row in security.data:
218
219
  str_date = row[date_index]
219
220
  if str_date not in (
220
- c2cciutils.security.SUPPORT_TO_BE_DEFINED,
221
- c2cciutils.security.SUPPORT_BEST_EFFORT,
222
- c2cciutils.security.SUPPORT_UNSUPPORTED,
221
+ security_md.SUPPORT_TO_BE_DEFINED,
222
+ security_md.SUPPORT_BEST_EFFORT,
223
+ security_md.SUPPORT_UNSUPPORTED,
223
224
  ):
224
225
  date = datetime.datetime.strptime(row[date_index], "%d/%m/%Y")
225
226
  if date < datetime.datetime.now():
@@ -456,18 +456,15 @@ K8S_DB_CHART_OPTIONS_DEFAULT = {
456
456
 
457
457
 
458
458
  PRINT_VERSIONS_VERSIONS_DEFAULT = [
459
- {"name": "c2cciutils", "cmd": ["c2cciutils", "--version"]},
460
459
  {"name": "python", "cmd": ["python3", "--version"]},
461
460
  {"name": "pip", "cmd": ["python3", "-m", "pip", "--version"]},
462
- {"name": "twine", "cmd": ["twine", "--version"]},
463
461
  {"name": "node", "prefix": "node ", "cmd": ["node", "--version"]},
464
462
  {"name": "npm", "prefix": "npm ", "cmd": ["npm", "--version"]},
465
- {"name": "make", "cmd": ["make", "--version"], "prefix": "make "},
463
+ {"name": "make", "cmd": ["make", "--version"]},
466
464
  {"name": "docker", "cmd": ["docker", "--version"]},
467
465
  {"name": "docker compose", "cmd": ["docker", "compose", "version"]},
468
466
  {"name": "java", "cmd": ["java", "-version"]},
469
- {"name": "kubectl", "cmd": ["kubectl", "version"]},
470
- {"name": "helm", "cmd": ["helm", "version"]},
467
+ {"name": "helm", "cmd": ["helm", "version"], "prefix": "HELM: "},
471
468
  ]
472
469
  """ Default value of the field path 'Print versions versions' """
473
470
 
@@ -582,10 +579,6 @@ class PrintVersions(TypedDict, total=False):
582
579
  Print versions versions.
583
580
 
584
581
  default:
585
- - cmd:
586
- - c2cciutils
587
- - --version
588
- name: c2cciutils
589
582
  - cmd:
590
583
  - python3
591
584
  - --version
@@ -596,10 +589,6 @@ class PrintVersions(TypedDict, total=False):
596
589
  - pip
597
590
  - --version
598
591
  name: pip
599
- - cmd:
600
- - twine
601
- - --version
602
- name: twine
603
592
  - cmd:
604
593
  - node
605
594
  - --version
@@ -614,7 +603,6 @@ class PrintVersions(TypedDict, total=False):
614
603
  - make
615
604
  - --version
616
605
  name: make
617
- prefix: 'make '
618
606
  - cmd:
619
607
  - docker
620
608
  - --version
@@ -628,14 +616,11 @@ class PrintVersions(TypedDict, total=False):
628
616
  - java
629
617
  - -version
630
618
  name: java
631
- - cmd:
632
- - kubectl
633
- - version
634
- name: kubectl
635
619
  - cmd:
636
620
  - helm
637
621
  - version
638
622
  name: helm
623
+ prefix: 'HELM: '
639
624
  """
640
625
 
641
626
 
@@ -451,18 +451,15 @@
451
451
  "title": "Print versions versions",
452
452
  "type": "array",
453
453
  "default": [
454
- { "name": "c2cciutils", "cmd": ["c2cciutils", "--version"] },
455
454
  { "name": "python", "cmd": ["python3", "--version"] },
456
455
  { "name": "pip", "cmd": ["python3", "-m", "pip", "--version"] },
457
- { "name": "twine", "cmd": ["twine", "--version"] },
458
456
  { "name": "node", "prefix": "node ", "cmd": ["node", "--version"] },
459
457
  { "name": "npm", "prefix": "npm ", "cmd": ["npm", "--version"] },
460
- { "name": "make", "cmd": ["make", "--version"], "prefix": "make " },
458
+ { "name": "make", "cmd": ["make", "--version"] },
461
459
  { "name": "docker", "cmd": ["docker", "--version"] },
462
460
  { "name": "docker compose", "cmd": ["docker", "compose", "version"] },
463
461
  { "name": "java", "cmd": ["java", "-version"] },
464
- { "name": "kubectl", "cmd": ["kubectl", "version"] },
465
- { "name": "helm", "cmd": ["helm", "version"] }
462
+ { "name": "helm", "cmd": ["helm", "version"], "prefix": "HELM: " }
466
463
  ],
467
464
  "items": {
468
465
  "type": "object",
@@ -27,11 +27,8 @@ def main() -> None:
27
27
  print(yaml.dump(c2cciutils.get_config(), default_flow_style=False, Dumper=yaml.SafeDumper))
28
28
 
29
29
  if args.version:
30
- for pkg in ("c2cciutils", "black", "isort"):
31
- try:
32
- print(f"{pkg} {pkg_resources.get_distribution(pkg).version}")
33
- except pkg_resources.DistributionNotFound:
34
- print(f"{pkg} missing")
30
+ version = pkg_resources.get_distribution("c2cciutils").version
31
+ print(f"c2cciutils {version}")
35
32
 
36
33
  if args.ls_files_mime:
37
34
  for file_name in c2cciutils.get_git_files_mime(args.ls_files_mime):
@@ -13,6 +13,7 @@ from re import Match
13
13
  from typing import Optional, cast
14
14
 
15
15
  import requests
16
+ import security_md
16
17
  import yaml
17
18
 
18
19
  import c2cciutils
@@ -21,7 +22,6 @@ import c2cciutils.env
21
22
  import c2cciutils.lib.docker
22
23
  import c2cciutils.publish
23
24
  import c2cciutils.scripts.download_applications
24
- import c2cciutils.security
25
25
  from c2cciutils.publish import GoogleCalendar
26
26
  from c2cciutils.scripts.trigger_image_update import dispatch
27
27
 
@@ -213,7 +213,7 @@ def main() -> None:
213
213
  print(f"::error:: {security_response.status_code} {security_response.text}")
214
214
  sys.exit(1)
215
215
 
216
- security = c2cciutils.security.Security(security_text)
216
+ security = security_md.Security(security_text)
217
217
  version_index = security.version_index
218
218
  alternate_tag_index = security.alternate_tag_index
219
219
 
@@ -19,7 +19,7 @@ strict = true
19
19
 
20
20
  [tool.poetry]
21
21
  name = "c2cciutils"
22
- version = "1.7.0.dev277"
22
+ version = "1.7.0.dev281"
23
23
  description = "Common utilities for Camptocamp CI"
24
24
  readme = "README.md"
25
25
  authors = ["Camptocamp <info@camptocamp.com>"]
@@ -50,7 +50,6 @@ c2cciutils-env = "c2cciutils.scripts.env:main"
50
50
  c2cciutils-publish = "c2cciutils.scripts.publish:main"
51
51
  c2cciutils-version = "c2cciutils.scripts.version:main"
52
52
  c2cciutils-clean = "c2cciutils.scripts.clean:main"
53
- c2cciutils-security-md = "c2cciutils.scripts.security_md:main"
54
53
  c2cciutils-checks = "c2cciutils.scripts.env:main"
55
54
  c2cciutils-pull-request-checks = "c2cciutils.scripts.pr_checks:main"
56
55
  c2cciutils-audit = "c2cciutils.scripts.audit:main"
@@ -84,6 +83,7 @@ debian-inspector = "31.1.0"
84
83
  PyYAML = "6.0.2"
85
84
  tomlkit = { version = "0.13.2", optional = true }
86
85
  multi-repo-automation = { version="1.3.0", optional = true }
86
+ security-md = "0.2.3"
87
87
 
88
88
  [tool.poetry.extras]
89
89
  audit = []
@@ -16,6 +16,7 @@ install_requires = \
16
16
  'python-magic>=0.0.0,<1.0.0',
17
17
  'requests>=2.0.0,<3.0.0',
18
18
  'ruamel.yaml>=0.0.0,<1.0.0',
19
+ 'security-md>=0.0.0,<1.0.0',
19
20
  'toml>=0.0.0,<1.0.0']
20
21
 
21
22
  extras_require = \
@@ -53,15 +54,13 @@ entry_points = \
53
54
  'c2cciutils-publish = c2cciutils.scripts.publish:main',
54
55
  'c2cciutils-pull-request-checks = '
55
56
  'c2cciutils.scripts.pr_checks:main',
56
- 'c2cciutils-security-md = '
57
- 'c2cciutils.scripts.security_md:main',
58
57
  'c2cciutils-trigger-image-update = '
59
58
  'c2cciutils.scripts.trigger_image_update:main',
60
59
  'c2cciutils-version = c2cciutils.scripts.version:main']}
61
60
 
62
61
  setup_kwargs = {
63
62
  'name': 'c2cciutils',
64
- 'version': '1.7.0.dev277',
63
+ 'version': '1.7.0.dev281',
65
64
  'description': 'Common utilities for Camptocamp CI',
66
65
  'long_description': '# C2C CI utils\n\n## Publishing\n\nThe main goals of C2C CI utils is to offer the commands to publish the project,\nsee the [documentation](https://github.com/camptocamp/c2cciutils/wiki/Publishing).\n\n## Changelog\n\nWhen we create a tag by default with the `changelog` workflow a release is created on GitHub, a changelog is\ngenerated and added to the release.\n\n## Security\n\nThe security is managed by the `c2cciutils-audit` command with Snyk, it will audit the dependencies of the project on every\nstabilization branches, if possible a pull request is created automatically to update the dependencies.\n\nWhen we publish a Docker image the generated image is monitored by Snyk, this means that Snyk will search\nfor all the dependencies and send the list to the Snyk web site to be monitored.\nWe also do a test of the image and log the result (This will never cause the build to fail).\n\n## Checks\n\nC2C CI utils will no more provide a tool to do a check of the project, this is replaced by `pre-commit`,\na base configuration is provided in the example project.\n\n## Pull request checks\n\nA workflow is provided to run the checks on the pull requests, it will run the `c2cciutils-pr-checks` command.\n\n- Check that the commit message and the pull request title start with a capital letter.\n- Check that there aren\'t any spelling issue in the commit message and in the pull request title.\n- Add a message to the pull request with a link to the JIRA issue if the pull request branch name starts with\n `[a-zA-Z]+-[0-9]+-` or end with `-[a-zA-Z]+-[0-9]+`.\n\n## Dependencies\n\nIn the example project there is a basic Renovate configuration, it will update the dependencies of the project.\nThere is also a workflow to add a review on the Renovate pull requests to make the auto merge working on\nrepository that required a review.\n\n## Backports\n\nA workflow is provided to backport the pull requests on the stabilization branches, it will be triggered by\nadding a label named `backport <destination_branch>` on the pull request.\n\n## Old workflows\n\nGitHub will retain all the old workflows, so we need to delete them, the `delete-old-workflows-run`\nworkflow will delete the workflows older than 500 days.\n\n## Workflows\n\nC2cciutils make easier to have those workflows in a project:\n\n- `audit.yaml`: Audit the stabilization branches of the application against vulnerabilities in the python and node dependency\n- `auto-review.yaml`: Auto review the Renovate pull requests\n- `backport.yaml`: Trigger the backports (work with labels)\n- `clean.yaml`: Clean the Docker images related on a deleted feature branch\n- `main.yaml`: Main workflow especially with the c2cciutils-checks command\n- `changelog.yaml`: Generate the changelog and create the release on GitHub\n- `delete-old-workflows-run.yaml`: Delete the old workflows\n- `pr-checks.yaml`: Run the checks on the pull requests\n\nAll the provided commands used in the workflow:\n\n- `c2cciutils`: some generic tools.\n- `c2cciutils-version`: Create a new version of the project.\n- `c2cciutils-checks`: Run the checks on the code (those checks don\'t need any project dependencies).\n- `c2cciutils-audit`: Do the audit, the main difference with checks is that it can change between runs on the same code.\n- `c2cciutils-publish`: Publish the project.\n- `c2cciutils-clean`: Delete Docker images on Docker Hub after corresponding branch have been deleted.\n\n## Utilities\n\nThe following utilities are provided:\n\n- `c2cciutils`: some generic tools.\n- `c2cciutils-download-applications`: Download the applications with version managed by Renovate, see below.\n- `c2cciutils-docker-logs`: Display the logs of the application in Docker (compose).\n- `c2cciutils-k8s-install`: Install a k3d / k3s cluster, see below.\n- `c2cciutils-k8s-logs`: Display the logs of the application in the k8s cluster, see below.\n- `c2cciutils-k8s-db`: Create a database in the k8s cluster, see below.\n- `c2cciutils-k8s-wait`: Wait that the application started correctly in the cluster, see below.\n- `c2cciutils-docker-versions-gen`: Generate the Docker package versions file (`ci/dpkg-versions.yaml`), see below.\n- `c2cciutils-pin-pipenv`: Display all the dependencies that\'s in the `Pipenv.lock` but not in the `Pipenv` to be able to pin them.\n- `c2cciutils-trigger-image-update`: Trigger the ArgoCD repository about image update on the CI (automatically done in the publishing).\n- `c2cciutils-google-calendar`: Tool to test the Google credentials for calendar API and refresh them if needed. See `c2cciutils-google-calendar -h` for more information.\n\n## New project\n\nThe content of `example-project` can be a good base for a new project.\n\n## New version\n\nRequirements: the right version (>= 1.6) of `c2cciutils` should be installed with the `version` extra.\n\nTo create a new minor version you just should run `c2cciutils-version --version=<version>`.\n\nYou are welcome to run `c2cciutils-version --help` to see what\'s it\'s done.\n\nNote that it didn\'t create a tag, you should do it manually.\n\nTo create a patch version you should just create tag.\n\n## Secrets\n\nIn the CI we need to have the following secrets::\n\n- `HAS_SECRETS` to be set to \'HAS_SECRETS\', to avoid error errors from external\n pull requests, already set globally on Camptocamp organization.\n- `GOPASS_CI_GITHUB_TOKEN` and `CI_GPG_PRIVATE_KEY` required to initialize the gopass password store,\n the secrets exists in the Camptocamp organization but not shared on all project, then you should add\n your project to the shared list.\n\n## Use locally, in the projects that use c2cciutils\n\nInstall it: `python3 -m pip install --user --requirement ci/requirements.txt`\nDry run publish: `GITHUB_REF=... c2cciutils-publish --dry-run ...`\n\n## Configuration\n\nYou can get the current configuration with `c2cciutils --get-config`, the default configuration depends on your project.\nNote that it didn\'t contain the default defined the schema and visible in the [generated documentation](./config.md).\n\nYou can override the configuration with the file `ci/config.yaml`.\n\nAt the base of the configuration you have:\n\n- `version`: Contains some regular expressions to find the versions branches and tags, and to convert them into application versions.\n- `audit`: The audit configuration, see `c2cciutils/audit.py` for more information.\n- `publish`: The publishing configuration, see `c2cciutils/publish.py` for more information.\n\nMany actions can be disabled by setting the corresponding configuration part to `False`.\n\n## SECURITY.md\n\nThe `SECURITY.md` file should contain the security policy of the repository, especially the end of\nsupport dates.\n\nFor compatibility with `c2cciutils` it should contain an array with at least the columns\n`Version` and `Supported Until`. The `Version` column will contain the concerned version.\nThe `Supported Until` will contain the date of end of support `dd/mm/yyyy`.\nIt can also contain the following sentences:\n\n- `Unsupported`: no longer supported => no audit, no rebuild.\n- `Best effort`: the support is ended, it is still rebuilt and audited, but this can be stopped without any notice.\n- `To be defined`: not yet released or the date will be set related of another project release date (like for GeoMapFish).\n\nSee also [GitHub Documentation](https://docs.github.com/en/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository)\n\n## IDE\n\nThe IDE should be configured as:\n\n- using `black` and `isort` without any arguments,\n- using the `editorconfig` configuration.\n\n### VScode\n\n- Recommend extensions to work well with c2cciutils:\n - [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) And use EditorConfig\n - [shell-format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format) With the configuration\n `"shellformat.flag": "-bn"`.\n - [Better TOML](https://marketplace.visualstudio.com/items?itemName=bodil.prettier-toml)\n- Other recommend extensions:\n - [hadolint](https://marketplace.visualstudio.com/items?itemName=exiasr.hadolint)\n - [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)\n\nSelect a formatter:\n\n- `CTRL+MAJ+P`\n- Format document With...\n- Configure Default Formatter...\n- Select the formatter\n\n## Publishing\n\n### To pypi\n\nThe config is like this:\n\n```yaml\nversions:\n # List of kinds of versions you want to publish, that can be:\n # rebuild (specified with --type),\n # version_tag, version_branch, feature_branch, feature_tag (for pull request)\n```\n\nIt we have a `setup.py` file, we will be in legacy mode:\nWhen publishing, the version computed from arguments or `GITHUB_REF` is put in environment variable `VERSION`, thus you should use it in `setup.py`, example:\n\n```python\nVERSION = os.environ.get("VERSION", "1.0.0")\n```\n\nAlso 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.\n\nExample of configuration:\n\n```toml\n[tool.poetry-dynamic-versioning]\nenable = true\nvcs = "git"\npattern = "^(?P<base>\\\\d+(\\\\.\\\\d+)*)"\nformat-jinja = """\n{%- if env.get("VERSION_TYPE") == "version_branch" -%}\n{{serialize_pep440(bump_version(base, 1 if env.get("IS_MASTER") == "TRUE" else 2), dev=distance)}}\n{%- elif distance == 0 -%}\n{{serialize_pep440(base)}}\n{%- else -%}\n{{serialize_pep440(bump_version(base), dev=distance)}}\n{%- endif -%}\n"""\n\n```\n\nNote that we can access to the environment variables `VERSION`,`VERSION_TYPE` and `IS_MASTER`.\n\nThen by default:\n\n- Tag with `1.2.3` => release `1.2.3`\n- Commit on feature branch just do a validation\n- Commit on `master` branch after the tag 1.3.0 => release `1.4.0.dev1`\n- Commit on `1.3` branch after the tag 1.3.0 => release `1.3.1.dev1`\n\nTo make it working in the `Dockerfile` you should have in the `poetry` stage:\n\n```Dockerfile\nENV POETRY_DYNAMIC_VERSIONING_BYPASS=dev\nRUN poetry export --extras=checks --extras=publish --extras=audit --output=requirements.txt \\\n && poetry export --with=dev --output=requirements-dev.txt\n```\n\nAnd in the `run` stage\n\n```Dockerfile\nARG VERSION=dev\nRUN --mount=type=cache,target=/root/.cache \\\n POETRY_DYNAMIC_VERSIONING_BYPASS=${VERSION} python3 -m pip install --disable-pip-version-check --no-deps --editable=.\n```\n\nAnd in the `Makefile`:\n\n```Makefile\nVERSION = $(strip $(shell poetry version --short))\n\n.PHONY: build\nbuild: ## Build the Docker images\n docker build --build-arg=VERSION=$(VERSION) --tag=$(GITHUB_REPOSITORY) .\n```\n\n### To Docker registry\n\nThe config is like this:\n\n```yaml\nlatest: True\nimages:\n - # The base name of the image we want to publish\n name:\nrepository:\n <internal_name>:\n # The fqdn name of the server if not Docker hub\n server:\n # List of kinds of versions you want to publish, that can be: rebuild (specified using --type),\n # version_tag, version_branch, feature_branch, feature_tag (for pull request)\n version:\n # List of tags we want to publish interpreted with `format(version=version)`\n # e.g. if you use `{version}-lite` when you publish the version `1.2.3` the source tag\n # (that should be built by the application build) is `latest-lite`, and it will be published\n # with the tag `1.2.3-lite`.\n tags:\n # If your images are published by different jobs you can separate them in different groups\n # and publish them with `c2cciutils-publish --group=<group>`\n group:\n```\n\nBy default, the last line of the `SECURITY.md` file will be published (`docker`) with the tag\n`latest`. Set `latest` to `False` to disable it.\n\nWith the `c2cciutils-clean` the images on Docker hub for `feature_branch` will be removed on branch removing.\n\n## Download applications\n\nIn case some executables or applications from GitHub releases or any other URLs are required on the CI host\nand are not handled by any dependency manager, we provide a set of tools to install them and manage upgrades\nthrough Renovate.\n\nCreate an application file (e.-g. `applications.yaml`) with:\n\n```yaml\n# yaml-language-server: $schema=https://raw.githubusercontent.com/camptocamp/c2cciutils/master/c2cciutils/schema-applications.json\n\n# Application from GitHub release\n<organization>/<project>:\n get-file-name: <file name present in the release>\n to-file-name: <The file name you want to create in ~/.local/bin>\n finish-command: # The command you want to run after the file is downloaded\n - - chmod # To be executable (usually required)\n - +x\n - <to-file-name>\n - - <to-file-name> # Print the version of the application\n - --version\n# Application from GitHub release in a tar file (or tar.gz)\n<organization>/<project>:\n get-file-name: <file name present in the release>\n type: tar\n tar-file-name: <The file name available in the tar file>\n to-file-name: <The file name you want to create in ~/.local/bin>\n finish-command: [...] # The command you want to run after the file is downloaded\n# Application from an URL\n<application reference name>:\n url-pattern: <The URL used to download the application>\n to-file-name: <The file name you want to create in ~/.local/bin>\n finish-command: [...] # The command you want to run after the file is downloaded\n```\n\nIn the attributes `url-pattern`, `get-file-name` you can use the following variables:\n\n- `{version}`: The version of the application present in the version file.\n- `{version_quote}`: The URL encoded version.\n- `{short_version}`: The version without the `v` prefix.\n\nThe `applications-versions.yaml` file is a map of applications and their versions.\n\nAdd in your Renovate configuration:\n\n```json5\n regexManagers: [\n {\n fileMatch: [\'^applications-versions.yaml$\'],\n matchStrings: [\n \'(?<depName>[^\\\\s]+): (?<currentValue>[^\\\\s]+) # (?<datasource>[^\\\\s]+)\',\n ],\n },\n ],\n```\n\nNow you need to call `c2cciutils-download-applications --applications-file=applications.yaml --versions-file=applications-version.yaml`\nto install required applications on CI host before using them (an already installed application is installed only if needed).\n\n## Use Renovate to trigger a new build instead of the legacy rebuild\n\nRun the command `c2cciutils-docker-versions-gen camptocamp/image[:tag]` to generate a file that is a kind of package lock of the Debian packages in the file `ci/dpkg-versions.yaml`.\n\nAdd in your renovate configuration:\n\n```javascript\n regexManagers: [\n {\n fileMatch: [\'^ci/dpkg-versions.yaml$\'],\n matchStrings: [" *(?<depName>[^\'\\\\s]+): \'?(?<currentValue>[^\'\\\\s/]*[0-9][^\'\\\\s/]*)\'?"],\n datasourceTemplate: \'repology\',\n versioningTemplate: \'loose\',\n },\n ],\n```\n\nWhen a new version of a Debian package will be available:\n\n- Renovate will automatically open a pull request to update the file `ci/dpkg-versions.yaml`.\n- And the continuous integration will build a new fresh Docker image with latest versions of all Debian packages.\n\n## Kubernetes\n\nC2cciutils provide some commands for Kubernetes.\n\nYou can define a workflow like that:\n\n```yaml\n- name: Install k3s/k3d (Kubernetes cluster)\n run: c2cciutils-k8s-install\n\n- name: Create a database to do the tests\n run: c2cciutils-k8s-db --script=<my_script>.sql\n\n- name: Install the application in the Kubernetes cluster\n run: kubectl apply -f <my_application>.yaml\n\n- name: Wait that the application is ready\n run: c2cciutils-k8s-wait\n- name: Print the application status and logs\n run: c2cciutils-k8s-logs\n if: always()\n\n- name: Uninstall the application\n run: kubectl delete -f <my_application>.yaml || true\n\n- name: Cleanup the database\n run: c2cciutils-k8s-db --cleanup\n```\n\n`c2cciutils-k8s-install` can be configured in the `ci/config.yaml` file, in section `k8s/k3d/install-commands`, default is:\n\n```yaml\n- - k3d\n cluster\n create\n test-cluster\n --no-lb\n --no-rollback\n```\n\nSee also: [K3d cluster create documentation](https://k3d.io/v4.4.8/usage/commands/k3d_cluster_create/).\n\n`c2cciutils-k8s-db` can be configured in the `ci/config.yaml` file, in section `k8s/db/chart-options`, default is:\n\n```yaml\npersistence.enabled: \'false\'\ntls.enabled: \'true\'\ntls.autoGenerated: \'true\'\npostgresqlPassword: mySuperTestingPassword\nvolumePermissions.enabled: \'true\'\n```\n\nSee also: [Parameters documentations](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#parameters).\n\n## Contributing\n\nInstall the pre-commit hooks:\n\n```bash\npip install pre-commit\npre-commit install --allow-missing-config\n```\n',
67
66
  'author': 'Camptocamp',
@@ -1,112 +0,0 @@
1
- """
2
- Read the table of versions from SECURITY.md.
3
- """
4
-
5
- import xml.etree.ElementTree # nosec
6
- from typing import Optional
7
-
8
- import markdown
9
- from markdown.extensions.tables import TableExtension
10
-
11
- HEADER_VERSION = "Version"
12
- HEADER_ALTERNATE_TAG = "Alternate Tag"
13
- HEADER_SUPPORTED_UNTIL = "Supported Until"
14
- SUPPORT_TO_BE_DEFINED = "To be defined"
15
- SUPPORT_BEST_EFFORT = "Best effort"
16
- SUPPORT_UNSUPPORTED = "Unsupported"
17
-
18
-
19
- class Security:
20
- """
21
- Read the table of versions from SECURITY.md.
22
- """
23
-
24
- headers: list[str]
25
- data: list[list[str]]
26
- _row: Optional[list[str]] = None
27
-
28
- def __init__(self, status: str, check: bool = True):
29
- """
30
- Initialize.
31
-
32
- Arguments:
33
- status: the content of the SECURITY.md file.
34
- check: Set to `False` to skip the check.
35
- """
36
-
37
- self.headers = []
38
- self.data = []
39
-
40
- markdown_instance = markdown.Markdown(extensions=[TableExtension()])
41
-
42
- elem = markdown_instance.parser.parseDocument(
43
- [s for s in status.split("\n") if s != "" and s[0] == "|"]
44
- )
45
- self._pe(elem.getroot())
46
-
47
- self.data = [r for r in self.data if len([c for c in r if c is not None]) > 0]
48
-
49
- self.version_index = self.headers.index(HEADER_VERSION) if HEADER_VERSION in self.headers else -1
50
- self.alternate_tag_index = (
51
- self.headers.index(HEADER_ALTERNATE_TAG) if HEADER_ALTERNATE_TAG in self.headers else -1
52
- )
53
- self.support_until_index = (
54
- self.headers.index(HEADER_SUPPORTED_UNTIL) if HEADER_SUPPORTED_UNTIL in self.headers else -1
55
- )
56
-
57
- # Check the content if the content isn't empty
58
- if check and status:
59
- if not self.check(verbose=0):
60
- raise ValueError("SECURITY.md file is not valid.")
61
-
62
- def check(self, verbose: int = -1) -> bool:
63
- """
64
- Check the content.
65
-
66
- Arguments:
67
- verbose: the verbosity level, `-1` for no output, `0` for errors only, `1` for all.
68
-
69
- Return:
70
- `True` if the content is valid, `False` otherwise.
71
- """
72
-
73
- success = True
74
- if self.version_index == -1:
75
- if verbose >= 0:
76
- print("`Version` column not found.")
77
- success = False
78
- elif verbose >= 1:
79
- print(f"`Version` column found at index {self.version_index}.")
80
-
81
- if self.alternate_tag_index == -1:
82
- if verbose >= 1:
83
- print("Optional `Alternate Tag` column not found.")
84
- elif verbose >= 1:
85
- print(f"`Alternate Tag` column found at index {self.alternate_tag_index}.")
86
-
87
- if self.support_until_index == -1:
88
- if verbose >= 0:
89
- print("`Supported Until` column not found.")
90
- success = False
91
- elif verbose >= 1:
92
- print(f"`Supported Until` column found at index {self.support_until_index}.")
93
-
94
- return success
95
-
96
- def _pe(self, elem: xml.etree.ElementTree.Element) -> None:
97
- """
98
- Parse the HTML table.
99
-
100
- Arguments:
101
- elem: The XML element
102
- """
103
- if elem.tag == "th":
104
- assert elem.text is not None
105
- self.headers.append(elem.text)
106
- if elem.tag == "tr":
107
- self._row = []
108
- self.data.append(self._row)
109
- if elem.tag == "td":
110
- self._row.append(elem.text) # type: ignore
111
- for element in list(elem):
112
- self._pe(element)