Best Practices ============== When using these GitLab CI/CD templates, follow these recommended practices to ensure secure and reliable release workflows. Branch Protection ----------------- Use branch protection to ensure releases happen from controlled branches. This prevents unauthorized or accidental releases from feature branches. .. code-block:: yaml release-to-pypi: extends: .release_pypi only: - main - master Credential Management --------------------- Store tokens and credentials as **masked GitLab CI variables**: 1. Navigate to your project's **Settings > CI/CD > Variables** 2. Add your credentials as variables 3. Enable the **Masked** option to hide values in job logs 4. Enable the **Protected** option to restrict access to protected branches Prefer API Tokens ----------------- Prefer API tokens over passwords whenever supported: * **PyPI:** Use API tokens instead of account passwords * **Read the Docs:** Use project-specific API tokens * **Other services:** Follow their token-based authentication when available API tokens can be: * Scoped to specific permissions * Easily revoked without changing your account password * Generated separately for different projects or purposes Separate Workflows ------------------ Keep documentation builds separate from package publication unless atomic release workflows are required. This allows you to: * Update documentation independently of releases * Test documentation builds without triggering a release * Maintain more granular control over your CI/CD pipeline .. code-block:: yaml stages: - test - build-docs - release release-docs: extends: .release_read_the_docs stage: build-docs release-to-pypi: extends: .release_pypi stage: release needs: ["release-docs"] Version Tagging --------------- Use Git tags to trigger releases instead of branch names: .. code-block:: yaml release-to-pypi: extends: .release_pypi only: - tags This ensures that: * Releases are explicitly versioned * You maintain a clear history of releases * Rollbacks are easier to manage Testing Before Release ---------------------- Always run your test suite before release jobs: .. code-block:: yaml stages: - test - release test: stage: test script: - pip install -e .[dev] - pytest release-to-pypi: extends: .release_pypi stage: release needs: ["test"]