hatch-calvar-sample-gitlab 2026.1.20.7__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 (26) hide show
  1. hatch_calvar_sample_gitlab-2026.1.20.7/.gitignore +75 -0
  2. hatch_calvar_sample_gitlab-2026.1.20.7/.gitlab-ci.yml +313 -0
  3. hatch_calvar_sample_gitlab-2026.1.20.7/.pre-commit-config.yaml +61 -0
  4. hatch_calvar_sample_gitlab-2026.1.20.7/BRANCH_BASED_WORKFLOW_IMPLEMENTATION_PLAN.md +815 -0
  5. hatch_calvar_sample_gitlab-2026.1.20.7/CALVER_MIGRATION_GUIDE.md +527 -0
  6. hatch_calvar_sample_gitlab-2026.1.20.7/CALVER_QUICK_START.md +90 -0
  7. hatch_calvar_sample_gitlab-2026.1.20.7/CHANGELOG.md +42 -0
  8. hatch_calvar_sample_gitlab-2026.1.20.7/GITLAB_CI_TROUBLESHOOTING.md +298 -0
  9. hatch_calvar_sample_gitlab-2026.1.20.7/GITLAB_ENTERPRISE_CI_CD_STANDARDS.md +909 -0
  10. hatch_calvar_sample_gitlab-2026.1.20.7/LICENSE.txt +9 -0
  11. hatch_calvar_sample_gitlab-2026.1.20.7/Makefile +339 -0
  12. hatch_calvar_sample_gitlab-2026.1.20.7/PKG-INFO +460 -0
  13. hatch_calvar_sample_gitlab-2026.1.20.7/PYPI_TO_NEXUS_MIGRATION.md +688 -0
  14. hatch_calvar_sample_gitlab-2026.1.20.7/PYPROJECT_TOML_MIGRATION.md +324 -0
  15. hatch_calvar_sample_gitlab-2026.1.20.7/README.md +402 -0
  16. hatch_calvar_sample_gitlab-2026.1.20.7/create_sample_hatch_project_with_calver_and_release_automation_98fc61f5.plan.md +745 -0
  17. hatch_calvar_sample_gitlab-2026.1.20.7/file +0 -0
  18. hatch_calvar_sample_gitlab-2026.1.20.7/junit.xml +1 -0
  19. hatch_calvar_sample_gitlab-2026.1.20.7/pyproject.toml +214 -0
  20. hatch_calvar_sample_gitlab-2026.1.20.7/scripts/calc_version.py +192 -0
  21. hatch_calvar_sample_gitlab-2026.1.20.7/src/hatch_calvar_sample/__about__.py +34 -0
  22. hatch_calvar_sample_gitlab-2026.1.20.7/src/hatch_calvar_sample/__init__.py +8 -0
  23. hatch_calvar_sample_gitlab-2026.1.20.7/src/hatch_calvar_sample/cli.py +313 -0
  24. hatch_calvar_sample_gitlab-2026.1.20.7/tests/__init__.py +3 -0
  25. hatch_calvar_sample_gitlab-2026.1.20.7/tests/test_version_calc.py +173 -0
  26. hatch_calvar_sample_gitlab-2026.1.20.7/tests/test_version_cli.py +194 -0
@@ -0,0 +1,75 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # Hatch build artifacts
31
+ .hatch/
32
+
33
+ # Version file (generated during build/release)
34
+ src/hatch_calvar_sample/VERSION
35
+
36
+ # PyInstaller
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Virtual environments
55
+ venv/
56
+ env/
57
+ ENV/
58
+ env.bak/
59
+ venv.bak/
60
+
61
+ # IDEs
62
+ .vscode/
63
+ .idea/
64
+ *.swp
65
+ *.swo
66
+ *~
67
+ .DS_Store
68
+
69
+ # MyPy
70
+ .mypy_cache/
71
+ .dmypy.json
72
+ dmypy.json
73
+
74
+ # Ruff
75
+ .ruff_cache/
@@ -0,0 +1,313 @@
1
+ stages:
2
+ - test
3
+ - build
4
+ - release
5
+
6
+ variables:
7
+ PYTHON_VERSION: "3.11"
8
+ PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
9
+
10
+ # Cache pip dependencies
11
+ cache:
12
+ key: ${CI_COMMIT_REF_SLUG}
13
+ paths:
14
+ - .cache/pip
15
+ - venv/
16
+
17
+ # ============================================================================
18
+ # Test Jobs
19
+ # ============================================================================
20
+
21
+ .test_template: &test_template
22
+ image: python:${PYTHON_VERSION}
23
+ before_script:
24
+ - python --version
25
+ - python -m pip install --upgrade pip
26
+ - |
27
+ if [ ! -f src/hatch_calvar_sample/VERSION ]; then
28
+ VERSION=$(python scripts/calc_version.py --validate --pep440 || echo "0.0.0")
29
+ DEV_VERSION="${VERSION}.dev$(date +%s)"
30
+ echo "__version__ = \"${DEV_VERSION}\"" > src/hatch_calvar_sample/VERSION
31
+ echo "Generated VERSION file: ${DEV_VERSION}"
32
+ fi
33
+
34
+ test:
35
+ <<: *test_template
36
+ parallel:
37
+ matrix:
38
+ - PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11", "3.12"]
39
+ script:
40
+ - pip install -e .
41
+ - pip install pytest pytest-cov
42
+ - |
43
+ pytest tests/ \
44
+ --cov=src/hatch_calvar_sample \
45
+ --cov=scripts \
46
+ --cov-report=xml \
47
+ --cov-report=html \
48
+ --cov-report=term-missing \
49
+ --junit-xml=junit.xml \
50
+ -v
51
+ - |
52
+ if [ "$CI_COMMIT_REF_NAME" = "main" ] || [ "$CI_COMMIT_REF_NAME" = "master" ]; then
53
+ coverage report --fail-under=70 || echo "Coverage below 70% - warning only"
54
+ fi
55
+ coverage: '/TOTAL.*\s+(\d+%)$/'
56
+ artifacts:
57
+ when: always
58
+ reports:
59
+ junit: junit.xml
60
+ coverage_report:
61
+ coverage_format: cobertura
62
+ path: coverage.xml
63
+ paths:
64
+ - htmlcov/
65
+ - coverage.xml
66
+ - junit.xml
67
+ expire_in: 1 week
68
+ rules:
69
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
70
+ - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop"
71
+ - if: $CI_COMMIT_TAG
72
+
73
+ # ============================================================================
74
+ # Build Verification Jobs
75
+ # ============================================================================
76
+
77
+ build-verify:
78
+ image: python:${PYTHON_VERSION}
79
+ parallel:
80
+ matrix:
81
+ - PYTHON_VERSION: ["3.9", "3.11"]
82
+ script:
83
+ - python --version
84
+ - python -m pip install --upgrade pip
85
+ - |
86
+ VERSION=$(python scripts/calc_version.py --validate --pep440 || echo "0.0.0")
87
+ DEV_VERSION="${VERSION}.dev$(date +%s)"
88
+ echo "__version__ = \"${DEV_VERSION}\"" > src/hatch_calvar_sample/VERSION
89
+ echo "Generated VERSION: ${DEV_VERSION}"
90
+ - pip install hatch hatchling build twine
91
+ - hatch build
92
+ - echo "Built packages:"
93
+ - ls -la dist/
94
+ - twine check dist/*
95
+ - |
96
+ # Test wheel installation
97
+ python -m venv test-env
98
+ source test-env/bin/activate
99
+ pip install --upgrade pip
100
+ pip install dist/*.whl
101
+ python -c "import hatch_calvar_sample; print(f'Version: {hatch_calvar_sample.__version__}')"
102
+ calver-check --help
103
+ calver-check info || echo "Info command executed"
104
+ deactivate
105
+ - |
106
+ # Test sdist installation
107
+ python -m venv test-env-sdist
108
+ source test-env-sdist/bin/activate
109
+ pip install --upgrade pip
110
+ pip install dist/*.tar.gz
111
+ python -c "import hatch_calvar_sample; print(f'Version: {hatch_calvar_sample.__version__}')"
112
+ deactivate
113
+ - |
114
+ # Verify package metadata
115
+ echo "=== Package Metadata Verification ==="
116
+ pip install pkginfo
117
+ python -c "
118
+ from pkginfo import Wheel
119
+ import glob
120
+ wheel_files = glob.glob('dist/*.whl')
121
+ if wheel_files:
122
+ w = Wheel(wheel_files[0])
123
+ print(f'Name: {w.name}')
124
+ print(f'Version: {w.version}')
125
+ print(f'Summary: {w.summary}')
126
+ print(f'Author: {w.author}')
127
+ print(f'License: {w.license}')
128
+ print(f'Requires-Python: {w.requires_python}')
129
+ print(f'Classifiers: {w.classifiers[:3]}...')
130
+ "
131
+ artifacts:
132
+ paths:
133
+ - dist/
134
+ expire_in: 1 week
135
+ rules:
136
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
137
+ - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop"
138
+
139
+ # ============================================================================
140
+ # License Check Job
141
+ # ============================================================================
142
+
143
+ license-check:
144
+ image: python:3.11
145
+ script:
146
+ - python --version
147
+ - python -m pip install --upgrade pip
148
+ - |
149
+ if [ ! -f src/hatch_calvar_sample/VERSION ]; then
150
+ VERSION=$(python scripts/calc_version.py --validate --pep440 || echo "0.0.0")
151
+ DEV_VERSION="${VERSION}.dev$(date +%s)"
152
+ echo "__version__ = \"${DEV_VERSION}\"" > src/hatch_calvar_sample/VERSION
153
+ echo "Generated VERSION file: ${DEV_VERSION}"
154
+ fi
155
+ - pip install pip-licenses licensecheck
156
+ - pip install -e .
157
+ - |
158
+ echo "=== License Report ==="
159
+ pip-licenses --format=markdown --output-file=license-report.md || true
160
+ pip-licenses --format=json --output-file=license-report.json || true
161
+ echo ""
162
+ cat license-report.md || true
163
+ - |
164
+ echo "Checking for prohibited licenses..."
165
+ ALLOWED_LICENSES="MIT|BSD|Apache|ISC|PSF|Python|WTFPL|Unlicense|Public Domain|MPL|LGPL"
166
+ pip-licenses --format=csv | tail -n +2 | while IFS=',' read -r name version license; do
167
+ license=$(echo "$license" | tr -d '"')
168
+ if ! echo "$license" | grep -qiE "$ALLOWED_LICENSES"; then
169
+ if echo "$license" | grep -qiE "^GPL|GNU General Public"; then
170
+ echo "::warning::Package $name ($version) has license: $license - Review required"
171
+ fi
172
+ fi
173
+ done
174
+ echo "License check completed"
175
+ - licensecheck --zero || echo "License check completed with findings"
176
+ artifacts:
177
+ paths:
178
+ - license-report.md
179
+ - license-report.json
180
+ expire_in: 30 days
181
+ rules:
182
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
183
+ - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "master"
184
+ allow_failure: true
185
+
186
+ # ============================================================================
187
+ # Auto-Tag Job (runs on merge to main/master)
188
+ # ============================================================================
189
+
190
+ auto-tag:
191
+ stage: release
192
+ image: python:3.11
193
+ script:
194
+ - python --version
195
+ - python -m pip install --upgrade pip
196
+ - git fetch --tags --force
197
+ - |
198
+ VERSION=$(python scripts/calc_version.py --validate --pep440)
199
+ echo "Calculated version: $VERSION"
200
+ if ! [[ "$VERSION" =~ ^[0-9]{4}\.[0-9]{2}\.[0-9]{2}\.[0-9]+$ ]]; then
201
+ echo "Error: Invalid CalVer format: $VERSION"
202
+ exit 1
203
+ fi
204
+ - |
205
+ TAG_NAME="v${VERSION}"
206
+ if git rev-parse -q --verify "refs/tags/${TAG_NAME}" >/dev/null; then
207
+ echo "Tag ${TAG_NAME} already exists, skipping tag creation"
208
+ exit 0
209
+ fi
210
+ echo "Tag ${TAG_NAME} does not exist, will create it"
211
+ - |
212
+ TAG_NAME="v${VERSION}"
213
+ # Use GitLab API to create tag (requires GITLAB_TOKEN variable)
214
+ if [ -z "$GITLAB_TOKEN" ]; then
215
+ echo "Warning: GITLAB_TOKEN not set. Using git push with CI_JOB_TOKEN (may fail without proper permissions)."
216
+ git config user.name "GitLab CI"
217
+ git config user.email "gitlab-ci@gitlab.com"
218
+ git tag -a "${TAG_NAME}" -m "Release ${VERSION} (auto-created from merge to ${CI_COMMIT_REF_NAME})"
219
+ git push "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "${TAG_NAME}" || {
220
+ echo "Error: Failed to push tag. Please configure GITLAB_TOKEN CI/CD variable with api scope."
221
+ echo "Or grant write_repository permission to CI_JOB_TOKEN in project settings."
222
+ exit 1
223
+ }
224
+ else
225
+ # Use GitLab API to create tag
226
+ echo "Creating tag ${TAG_NAME} via GitLab API..."
227
+ curl --request POST \
228
+ --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
229
+ --header "Content-Type: application/json" \
230
+ --data "{\"tag_name\": \"${TAG_NAME}\", \"ref\": \"${CI_COMMIT_SHA}\", \"message\": \"Release ${VERSION} (auto-created from merge to ${CI_COMMIT_REF_NAME})\"}" \
231
+ "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/repository/tags"
232
+ echo "Created tag: ${TAG_NAME}"
233
+ fi
234
+ rules:
235
+ - if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
236
+ - if: $CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"
237
+ allow_failure: false
238
+
239
+ # ============================================================================
240
+ # Release Job (runs on tag push)
241
+ # ============================================================================
242
+
243
+ release:
244
+ stage: release
245
+ image: python:3.11
246
+ script:
247
+ - python --version
248
+ - |
249
+ # Extract version from tag (strip 'v' prefix)
250
+ if [[ "$CI_COMMIT_TAG" =~ ^v(.*)$ ]]; then
251
+ VERSION="${BASH_REMATCH[1]}"
252
+ else
253
+ VERSION="$CI_COMMIT_TAG"
254
+ fi
255
+ echo "Extracted version: $VERSION"
256
+ # Validate CalVer format: YYYY.MM.DD.MICRO
257
+ if ! [[ "$VERSION" =~ ^[0-9]{4}\.[0-9]{2}\.[0-9]{2}\.[0-9]+$ ]]; then
258
+ echo "Error: Invalid CalVer format: $VERSION"
259
+ echo "Expected format: YYYY.MM.DD.MICRO (e.g., 2024.01.18.1)"
260
+ exit 1
261
+ fi
262
+ echo "Validated version: $VERSION"
263
+ - |
264
+ echo "__version__ = \"${VERSION}\"" > src/hatch_calvar_sample/VERSION
265
+ cat src/hatch_calvar_sample/VERSION
266
+ - python -m pip install --upgrade pip
267
+ - pip install hatch hatchling build twine
268
+ - hatch build
269
+ - twine check dist/*
270
+ - |
271
+ # Publish to PyPI
272
+ # Note: Configure PYPI_API_TOKEN in GitLab CI/CD variables for PyPI publishing
273
+ # Create a PyPI API token at: https://pypi.org/manage/account/token/
274
+ echo "Debug: Checking for PYPI_API_TOKEN..."
275
+ echo "CI_COMMIT_TAG: ${CI_COMMIT_TAG}"
276
+ echo "CI_COMMIT_REF_NAME: ${CI_COMMIT_REF_NAME}"
277
+ echo "PYPI_API_TOKEN is set: $([ -n "$PYPI_API_TOKEN" ] && echo 'YES' || echo 'NO')"
278
+ echo "PYPI_API_TOKEN length: ${#PYPI_API_TOKEN}"
279
+ if [ -z "$PYPI_API_TOKEN" ]; then
280
+ echo ""
281
+ echo "ERROR: PYPI_API_TOKEN not set. Cannot publish to PyPI."
282
+ echo ""
283
+ echo "Common issues:"
284
+ echo "1. Variable is marked as 'Protected' but tag is not protected"
285
+ echo " Solution: Either uncheck 'Protected' flag OR protect the tag in Settings → Repository → Protected Tags"
286
+ echo "2. Variable has environment scope that doesn't match"
287
+ echo " Solution: Leave 'Environment scope' blank (all environments) or set it to 'pypi'"
288
+ echo "3. Variable name mismatch (case-sensitive)"
289
+ echo " Solution: Ensure variable key is exactly 'PYPI_API_TOKEN'"
290
+ echo ""
291
+ echo "To enable PyPI publishing:"
292
+ echo "1. Create a PyPI API token at https://pypi.org/manage/account/token/"
293
+ echo "2. Add it as a CI/CD variable named 'PYPI_API_TOKEN' in GitLab project settings"
294
+ echo " Settings → CI/CD → Variables → Add variable"
295
+ echo " - Key: PYPI_API_TOKEN (exact match, case-sensitive)"
296
+ echo " - Value: [your PyPI API token]"
297
+ echo " - Type: Variable"
298
+ echo " - Environment scope: (leave blank for all environments)"
299
+ echo " - Flags:"
300
+ echo " - Masked: Yes (recommended)"
301
+ echo " - Protected: No (unless tag is protected)"
302
+ echo " - Expand variable reference: No"
303
+ exit 1
304
+ fi
305
+ echo "Publishing to PyPI..."
306
+ twine upload --username __token__ --password "$PYPI_API_TOKEN" dist/*
307
+ echo "✓ Successfully published to PyPI: https://pypi.org/project/hatch-calvar-sample-gitlab/"
308
+ environment:
309
+ name: pypi
310
+ rules:
311
+ - if: $CI_COMMIT_TAG =~ /^v.*$/
312
+ when: on_success
313
+ allow_failure: false
@@ -0,0 +1,61 @@
1
+ # Pre-commit hooks configuration
2
+ # Install: pip install pre-commit && pre-commit install
3
+ # Run manually: pre-commit run --all-files
4
+
5
+ repos:
6
+ # General file checks
7
+ - repo: https://github.com/pre-commit/pre-commit-hooks
8
+ rev: v4.5.0
9
+ hooks:
10
+ - id: trailing-whitespace
11
+ - id: end-of-file-fixer
12
+ - id: check-yaml
13
+ - id: check-added-large-files
14
+ args: ['--maxkb=500']
15
+ - id: check-json
16
+ - id: check-toml
17
+ - id: detect-private-key
18
+ - id: check-case-conflict
19
+ - id: check-merge-conflict
20
+
21
+ # Python code formatting
22
+ - repo: https://github.com/psf/black
23
+ rev: 24.1.1
24
+ hooks:
25
+ - id: black
26
+ language_version: python3
27
+
28
+ # Import sorting
29
+ - repo: https://github.com/PyCQA/isort
30
+ rev: 5.13.2
31
+ hooks:
32
+ - id: isort
33
+ args: ['--profile=black']
34
+
35
+ # Python linting (Ruff)
36
+ - repo: https://github.com/astral-sh/ruff-pre-commit
37
+ rev: v0.1.9
38
+ hooks:
39
+ - id: ruff
40
+ args: [--fix, --exit-non-zero-on-fix]
41
+ - id: ruff-format
42
+
43
+ # Type checking (optional - may fail on Python 3.13.2 due to hashlib/blake2 issues)
44
+ - repo: https://github.com/pre-commit/mirrors-mypy
45
+ rev: v1.8.0
46
+ hooks:
47
+ - id: mypy
48
+ additional_dependencies: []
49
+ args: [--ignore-missing-imports]
50
+ exclude: ^(tests/|scripts/)
51
+ verbose: true
52
+ # Note: Python 3.13.2 has known issues with blake2b/blake2s in hashlib
53
+ # This hook may fail on Python 3.13.2 but works on other Python versions
54
+
55
+ # Security scanning
56
+ - repo: https://github.com/PyCQA/bandit
57
+ rev: 1.7.6
58
+ hooks:
59
+ - id: bandit
60
+ args: ['-ll', '-i', '-r']
61
+ exclude: ^tests/