ci(release): add release workflow to gitlab ci

Add automated release creation triggered by semantic version tags.
This commit is contained in:
Alexander Minges 2025-07-17 14:03:18 +02:00
parent 86c20c6d08
commit 774a3f7ecc
Signed by: Athemis
SSH key fingerprint: SHA256:TUXshgulbwL+FRYvBNo54pCsI0auROsSEgSvueKbkZ4
5 changed files with 367 additions and 0 deletions

View file

@ -10,6 +10,8 @@ stages:
- secret-detection
- build-docs
- pages
- build
- release
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
cache:
@ -78,5 +80,56 @@ pages:
only:
- main
build-package:
stage: build
image: python:3
before_script:
- python -m pip install --upgrade pip
- pip install build
script:
- python -m build
artifacts:
paths:
- dist/
expire_in: 1 week
rules:
- if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+.*$/
when: always
- when: never
release:
stage: release
image: registry.gitlab.com/gitlab-org/release-cli:latest
needs: ["test", "build-package"]
before_script:
- apk add --no-cache git python3 py3-pip
- python3 -m pip install setuptools_scm
script:
- |
# Get version from setuptools_scm
VERSION=$(python3 -c "from setuptools_scm import get_version; print(get_version())")
echo "Creating release for version: $VERSION"
# Extract changelog section for this version
CHANGELOG_SECTION=$(awk "/^## \[v?$VERSION\]/ {flag=1; next} /^## \[/ && flag {flag=0} flag" CHANGELOG.md | sed '/^$/d' || echo "No changelog entry found for version $VERSION")
# If changelog section is empty, provide a default message
if [ -z "$CHANGELOG_SECTION" ]; then
CHANGELOG_SECTION="Release $VERSION - See full changelog at $CI_PROJECT_URL/-/blob/v$VERSION/CHANGELOG.md"
fi
# Create GitLab release with artifacts
release-cli create \
--name "Release $VERSION" \
--tag-name "v$VERSION" \
--description "$CHANGELOG_SECTION" \
--ref "$CI_COMMIT_SHA" \
--assets-link "{\"name\":\"Source Distribution\",\"url\":\"$CI_PROJECT_URL/-/jobs/$CI_JOB_ID/artifacts/file/dist/doi2dataset-$VERSION.tar.gz\"}" \
--assets-link "{\"name\":\"Wheel Distribution\",\"url\":\"$CI_PROJECT_URL/-/jobs/$CI_JOB_ID/artifacts/file/dist/doi2dataset-$VERSION-py3-none-any.whl\"}"
rules:
- if: $CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+.*$/
when: always
- when: never
include:
- template: Security/Secret-Detection.gitlab-ci.yml

View file

@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `DATAVERSE_AUTH_PASSWORD` - Basic authentication password
- Environment variables take precedence over configuration file values
- Backward compatibility maintained - config file values used when environment variables are not set
- Automated tag-based release workflow with GitLab CI
- Release documentation in `docs/source/release-workflow.rst`
- Release process documentation in `CONTRIBUTING.md`
### Changed
@ -26,6 +29,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Expand automated commit ignoring for merge/revert/fixup/squash commits
- Update pre-commit CI messages to follow conventional commit format
- Improve commit message documentation with validation examples and best practices
- Enhanced GitLab CI pipeline with automated release stages
### Added (CI/CD)
- Automated package building (wheel and source distribution) on tag push
- GitLab release creation with changelog extraction
- Release artifact attachment (Python packages)
- Tag-based release triggering following semantic versioning
- Integration with existing setuptools_scm configuration
## [v2.0.3] - 2025-07-14

View file

@ -82,6 +82,7 @@ pytest --cov=. --cov-report=html
### Test Structure
Tests are organized into several files covering:
- Core functionality (DOI validation, name processing)
- API integration (mock responses)
- Citation building
@ -113,6 +114,61 @@ make multiversion
The documentation supports multiple versions and is automatically deployed via GitLab CI/CD.
## Release Process
This project uses automated tag-based releases following semantic versioning. Only maintainers can create releases.
### Creating a Release
1. **Update the changelog** in `CHANGELOG.md`:
```markdown
## [v2.0.4] - 2025-01-XX
### Added
- New feature description
### Fixed
- Bug fix description
```
2. **Commit the changelog update**:
```bash
git add CHANGELOG.md
git commit -m "docs: update changelog for v2.0.4"
```
3. **Create and push the release tag**:
```bash
git tag v2.0.4
git push origin v2.0.4
```
4. **GitLab CI automatically**:
- Runs all tests
- Builds Python packages (wheel and source distribution)
- Creates GitLab release with changelog content
- Attaches build artifacts to the release
### Version Numbering
- Follow [Semantic Versioning](https://semver.org/) (MAJOR.MINOR.PATCH)
- Tags must match the pattern `v[0-9]+.[0-9]+.[0-9]+` (e.g., `v2.0.4`)
- Pre-release versions are supported (e.g., `v2.0.4-rc.1`, `v2.0.4-alpha.1`)
### Release Artifacts
Each release automatically includes:
- Source distribution (`.tar.gz`)
- Wheel distribution (`.whl`)
- Changelog content extracted from `CHANGELOG.md`
- Documentation snapshot
## Submitting Changes
1. **Create a branch** from `main` for your changes
@ -135,6 +191,7 @@ Please be respectful and constructive in all interactions. We aim to maintain a
## Questions?
If you have questions about contributing, feel free to:
- Open an issue for discussion
- Check the existing documentation
- Contact the maintainers

View file

@ -41,4 +41,5 @@ Key Features:
modules
contributing
commit-messages
release-workflow
faq

View file

@ -0,0 +1,244 @@
Release Workflow
================
This project uses an automated tag-based release workflow that follows industry best practices and integrates seamlessly with GitLab CI/CD. Releases are triggered by pushing semantic version tags and include automatic changelog extraction, package building, and artifact distribution.
Overview
--------
The release process is designed to be simple, safe, and automated:
1. **Maintainer updates changelog** with new version information
2. **Maintainer creates and pushes a git tag** following semantic versioning
3. **GitLab CI automatically** builds packages and creates the release
4. **Release artifacts** are made available for download
This approach follows Git and industry conventions, ensuring compatibility with tools like ``setuptools_scm``, package managers, and dependency resolution systems.
For Maintainers: Creating a Release
------------------------------------
Prerequisites
~~~~~~~~~~~~~
- Write access to the main repository
- All changes merged to ``main`` branch
- Tests passing on the ``main`` branch
Step-by-Step Process
~~~~~~~~~~~~~~~~~~~~
1. **Update the Changelog**
Edit ``CHANGELOG.md`` to add a new version section:
.. code-block:: markdown
## [v2.0.4] - 2025-01-15
### Added
- New feature that enhances DOI processing
- Support for additional metadata fields
### Fixed
- Bug fix for edge case in affiliation parsing
- Improved error handling for malformed DOIs
### Changed
- Updated dependency versions for security
2. **Commit the Changelog**
Use a conventional commit message:
.. code-block:: bash
git add CHANGELOG.md
git commit -m "docs: update changelog for v2.0.4"
3. **Create and Push the Tag**
Create a semantic version tag and push it:
.. code-block:: bash
git tag v2.0.4
git push origin v2.0.4
4. **Monitor the Release**
GitLab CI will automatically:
- Run the full test suite
- Build Python packages (wheel and source distribution)
- Extract changelog content for the release description
- Create the GitLab release with downloadable artifacts
Automated Release Pipeline
---------------------------
The release pipeline consists of several stages:
Build Stage
~~~~~~~~~~~
When a semantic version tag is pushed:
- **Package Building**: Creates both wheel (``.whl``) and source distribution (``.tar.gz``) packages
- **Artifact Storage**: Packages are stored as CI artifacts for attachment to the release
- **Version Detection**: Uses ``setuptools_scm`` to automatically detect version from the git tag
Release Stage
~~~~~~~~~~~~~
After successful building:
- **Changelog Extraction**: Automatically parses ``CHANGELOG.md`` to extract content for the tagged version
- **Release Creation**: Creates a GitLab release with:
- Release name: "Release X.Y.Z"
- Tag reference: The pushed tag
- Description: Extracted changelog content
- Downloadable artifacts: Both wheel and source distributions
Version Numbering
------------------
This project follows `Semantic Versioning <https://semver.org/>`_ (SemVer):
Standard Versions
~~~~~~~~~~~~~~~~~
- **MAJOR.MINOR.PATCH** (e.g., ``v2.0.4``)
- **MAJOR**: Incompatible API changes
- **MINOR**: New functionality in a backward-compatible manner
- **PATCH**: Backward-compatible bug fixes
Pre-release Versions
~~~~~~~~~~~~~~~~~~~~
Pre-release versions are supported for testing:
- **Alpha**: ``v2.0.4-alpha.1``
- **Beta**: ``v2.0.4-beta.1``
- **Release Candidate**: ``v2.0.4-rc.1``
Tag Format Requirements
~~~~~~~~~~~~~~~~~~~~~~~
The CI pipeline only triggers on tags matching the pattern:
.. code-block:: text
^v[0-9]+\.[0-9]+\.[0-9]+.*$
Valid examples:
- ``v1.0.0``
- ``v2.1.3``
- ``v1.0.0-alpha.1``
- ``v2.0.0-rc.2``
Invalid examples:
- ``1.0.0`` (missing 'v' prefix)
- ``v1.0`` (missing patch version)
- ``release-1.0.0`` (wrong format)
Release Artifacts
-----------------
Each release includes the following downloadable artifacts:
Python Packages
~~~~~~~~~~~~~~~
- **Source Distribution** (``.tar.gz``): Contains all source code and can be installed with ``pip install``
- **Wheel Distribution** (``.whl``): Pre-built binary package for faster installation
Documentation
~~~~~~~~~~~~~
- **Documentation Snapshot**: The documentation website reflects the state at the time of release
- **Changelog**: Full changelog content is included in the release description
Installation from Release
~~~~~~~~~~~~~~~~~~~~~~~~~~
Users can install directly from release artifacts:
.. code-block:: bash
# Install from wheel (recommended)
pip install https://git.uni-due.de/cbm343e/doi2dataset/-/releases/v2.0.4/downloads/doi2dataset-2.0.4-py3-none-any.whl
# Install from source
pip install https://git.uni-due.de/cbm343e/doi2dataset/-/releases/v2.0.4/downloads/doi2dataset-2.0.4.tar.gz
Troubleshooting
---------------
Common Issues
~~~~~~~~~~~~~
**Pipeline doesn't trigger on tag push**
- Verify tag format matches ``v[0-9]+.[0-9]+.[0-9]+.*``
- Check that the tag was pushed to the main repository (not a fork)
- Ensure GitLab CI is enabled for the project
**Changelog extraction fails**
- Verify the changelog section follows the expected format: ``## [vX.Y.Z] - YYYY-MM-DD``
- Check that the version in the changelog matches the git tag
- Ensure the changelog file is named ``CHANGELOG.md`` and located in the project root
**Build artifacts missing**
- Check that the build stage completed successfully
- Verify ``setuptools_scm`` can detect the version from the git tag
- Ensure all required dependencies are available in the build environment
**Release creation fails**
- Verify the GitLab release CLI has necessary permissions
- Check that the tag doesn't already exist
- Ensure the changelog content doesn't contain special characters that break the release description
Manual Recovery
~~~~~~~~~~~~~~~
If the automated release fails, maintainers can:
1. **Check the CI logs** to identify the failure point
2. **Re-run failed jobs** from the GitLab CI interface
3. **Manually create the release** using the GitLab interface if needed
4. **Delete and recreate the tag** if there were issues with the tag itself
Best Practices
--------------
For Maintainers
~~~~~~~~~~~~~~~
- **Test thoroughly** before creating releases
- **Update documentation** alongside code changes
- **Follow semantic versioning** strictly
- **Write clear changelog entries** that help users understand changes
- **Use pre-release versions** for testing major changes
- **Coordinate releases** with other maintainers to avoid conflicts
For Contributors
~~~~~~~~~~~~~~~~
- **Write clear commit messages** following conventional commits
- **Update tests** for new functionality
- **Document changes** in pull requests
- **Consider backward compatibility** when making changes
- **Test with multiple Python versions** when possible
Security Considerations
-----------------------
- **Release artifacts** are publicly accessible
- **Changelog content** should not contain sensitive information
- **Version tags** are permanent and should not be deleted
- **CI pipeline** runs with elevated permissions during releases
The automated release process ensures consistency, reduces manual errors, and provides a clear audit trail for all releases.