Releasing opnDossier#
This document outlines the complete process for preparing and releasing a new version of opnDossier. The project uses GoReleaser for automated releases, git-cliff for changelog generation, and follows semantic versioning principles with comprehensive security compliance.
Overview#
The opnDossier release process is designed to be:
- Local-First: All commands run locally using the justfile and GoReleaser
- Consistent: Following conventional commits and semantic versioning
- Comprehensive: Includes binaries, Docker images, checksums, and SBOMs
- Secure: Includes SLSA Level 3 provenance, Cosign signatures, and comprehensive security scanning
- Security Compliant: Full compliance with industry security standards
Prerequisites#
Before starting a release, ensure you have:
-
Required Tools (managed via
mise install):git-clifffor changelog generationgoreleaserfor release automationcosignfor artifact signinggosecfor security scanning (runjust install-security-toolsif needed)cyclonedx-gomodfor SBOM generation (runjust install-security-toolsif needed)go-licensesfor third-party license notices generation- Proper GitHub permissions for the repository
-
Environment Setup:
GITHUB_TOKENwith appropriate permissions- For macOS notarization (optional):
MACOS_SIGN_P12MACOS_SIGN_PASSWORDMACOS_NOTARY_ISSUER_IDMACOS_NOTARY_KEY_IDMACOS_NOTARY_KEY
- For enhanced security scanning (optional):
SNYK_TOKENfor Snyk vulnerability scanningFOSSA_API_KEYfor FOSSA license analysis
-
Clean Working Directory:
git status # Should show no uncommitted changes git pull origin main # Ensure you're up to date -
Docker Login (for pushing container images):
echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
Release Process#
Step 1: Pre-Release Validation#
-
Run Full Test Suite:
just ci-fullThis runs:
- Pre-commit checks (
just check) - Code formatting checks (
just format-check) - Linting (
just lint) - All tests including integration tests (
just test,just test-integration) - Security scanning and SBOM generation (
just security-all) - GoReleaser configuration validation (
just release-check) - Documentation build (
just docs-test)
- Pre-commit checks (
-
Test Release Build (Optional but Recommended):
just release-snapshotThis creates a snapshot build without publishing to verify everything works.
-
Security Validation:
# Run all security checks (gosec + SBOM) just security-all # Or run individual checks just scan # Run gosec security scanner just sbom # Generate SBOM with cyclonedx-gomod
Step 2: Update Changelog#
The project uses git-cliff with conventional commits to automatically generate changelogs.
-
Generate Changelog for Unreleased Changes:
just changelog-unreleased -
Review the Generated Changelog:
- Open
CHANGELOG.mdand review the unreleased section - Ensure all important changes are captured
- Verify that conventional commit formatting is working correctly
- Open
-
Generate Changelog for Specific Version (if needed):
just changelog-version v1.2.3
Step 3: Version Tagging#
opnDossier follows semantic versioning (SemVer) with the format vMAJOR.MINOR.PATCH:
- MAJOR: Incompatible API changes or breaking changes
- MINOR: New functionality in a backwards compatible manner
- PATCH: Backwards compatible bug fixes
-
Create Version Tag:
# Replace X.Y.Z with your version number git tag vX.Y.ZNote: Don't push the tag yet - this will be done after the release is created.
Examples:
v1.0.0- First stable releasev1.1.0- New features addedv1.0.1- Bug fixes onlyv2.0.0-rc1- Release candidatev2.0.0-beta1- Beta release
Step 4: Local Release#
All releases are performed locally using the justfile commands:
-
Login to GitHub Container Registry (for Docker images):
echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin -
Run the Release:
just releaseThis runs
goreleaser release --cleanwhich:- Generates third-party license notices (
THIRD_PARTY_NOTICES) usingjust notices - Dynamically generates shell completions (bash, zsh, fish, PowerShell) using Cobra
- Dynamically generates man pages for all commands using Cobra
- Builds binaries for all platforms (FreeBSD, Linux, macOS, Windows)
- Creates archives with proper naming and includes LICENSE, README.md, CHANGELOG.md, THIRD_PARTY_NOTICES
- Generates native packages (.deb, .rpm, .apk, .pkg.tar.xz) with nfpm including:
- Man pages in
/usr/share/man/man1/ - Shell completions for bash, zsh, and fish
- Complete documentation including THIRD_PARTY_NOTICES
- Man pages in
- Generates checksums file (
opnDossier_checksums.txt) - Creates Software Bill of Materials (SBOM) for archives and packages
- Signs all artifacts with Cosign (keyless signing)
- Builds and pushes Docker images to GitHub Container Registry
- Creates the GitHub release with all artifacts attached
- Uses git-cliff generated changelog for release notes
- Generates third-party license notices (
-
Push the Git Tag (after successful release):
git push origin vX.Y.Z
Alternative: Snapshot Release#
For testing the release process without publishing:
just release-snapshot
This creates all artifacts locally but doesn't publish to GitHub or push Docker images.
Security Features#
Automated Security Scanning#
The release process includes comprehensive security scanning:
- Vulnerability Scanning: Grype scans all dependencies for known vulnerabilities
- SBOM Generation: Syft generates Software Bill of Materials in SPDX format
- License Analysis: FOSSA verifies license compliance
- Additional Security: Snyk provides enhanced vulnerability scanning
SLSA Level 3 Provenance#
Every release includes SLSA Level 3 provenance attestation:
- Build Integrity: Cryptographic proof of build process integrity
- Source Verification: Links artifacts to exact source code versions
- Build Environment: Documents the build environment and tools used
- Automated Generation: Generated automatically via GitHub Actions
Cosign Signatures#
All release artifacts are signed using Cosign:
- Keyless Signing: Uses OIDC-based keyless signing
- Artifact Verification: Users can verify artifact authenticity
- Bundle Format: Signatures include in-toto attestation bundles
- Automated Process: Integrated into the release workflow
Verification Commands#
Users can verify releases using:
# Verify checksums
sha256sum -c opnDossier_checksums.txt
# Verify Cosign signatures (requires cosign)
cosign verify-blob \
--bundle cosign.bundle \
opnDossier_checksums.txt
# Verify individual artifacts with Cosign
cosign verify-blob \
--bundle cosign.bundle \
opnDossier_Linux_x86_64.tar.gz
Note: SLSA provenance is generated via GitHub Actions for automated releases. For manual releases, SLSA provenance can be generated separately using the SLSA framework tools.
GoReleaser Configuration#
The .goreleaser.yaml file configures the following release artifacts:
Binaries#
- Platforms: FreeBSD, Linux, macOS, Windows
- Architectures: amd64, arm64 (FreeBSD arm64 excluded)
- Binary Name:
opndossier - Build Flags: CGO disabled, stripped binaries with version info
Archives#
- Format: tar.gz (zip for Windows)
- Naming:
opnDossier_OS_ARCHformat - Includes: LICENSE, README.md, CHANGELOG.md, THIRD_PARTY_NOTICES, man pages, shell completions
Docker Images#
Two Docker image variants are built:
-
Standard Image:
ghcr.io/evilbit-labs/opndossier:latestghcr.io/evilbit-labs/opndossier:vX.Y.Zghcr.io/evilbit-labs/opndossier:vX.Yghcr.io/evilbit-labs/opndossier:vX
-
POCL Variant:
- Same tags with
-poclsuffix - Uses different build branch
- Same tags with
Additional Artifacts#
- Checksums:
opnDossier_checksums.txt - SBOM: Software Bill of Materials for archives and packages
- License Notices:
THIRD_PARTY_NOTICESwith complete license attribution for all dependencies - Source Code: Automatically included
- Universal Binaries: For macOS (replaces individual arch binaries)
- The universal binary combines amd64 and arm64 architectures into a single
Darwin_allbinary - macOS code signing runs on the universal binary (not the individual arch binaries) via
universal_binaries.hooks.post - This ensures the signed artifact is what ships in release tarballs
- The universal binary combines amd64 and arm64 architectures into a single
Dynamic Documentation Generation#
opnDossier uses Cobra's built-in capabilities to dynamically generate shell completions and man pages during the release process. This ensures documentation is always current with the actual command structure.
Shell Completions#
The CLI supports generating completions for multiple shells:
# Generate bash completion
opndossier completion bash > ~/.bash_completion
# Generate zsh completion
opndossier completion zsh > "${fpath[1]}/_opndossier"
# Generate fish completion
opndossier completion fish > ~/.config/fish/completions/opndossier.fish
# Generate PowerShell completion
opndossier completion powershell > opndossier.ps1
Man Pages#
Generate comprehensive man pages for all commands:
# Generate man pages in current directory
opndossier man ./
# Generate man pages in system location
sudo opndossier man /usr/local/share/man/man1/
Release Integration#
During the release process, GoReleaser automatically:
- Generates third-party license notices using
go-licensesvia thejust noticescommand - Builds a temporary binary with correct version information
- Generates shell completions for bash, zsh, fish, and PowerShell
- Generates man pages for all commands and subcommands
- Includes these files in archives (under
man/opnDossier.1for man pages) and native packages (.deb, .rpm, .apk, .pkg.tar.xz) - Cleans up temporary files
This ensures that:
- Archive tarballs include man pages under
man/opnDossier.1 - Package installations include working completions and man pages
- Homebrew cask installations automatically install man pages, enabling
man opndossier - Documentation is always synchronized with the actual CLI interface
- No manual maintenance of static documentation files is required
- License attribution is transparent and complete for end users
Version Information#
Version information is injected into the binary at build time:
- Main Version: Set via ldflags in GoReleaser (
main.version) - Build Date: Available in CLI via
opndossier version - Git Commit: Available in CLI via
opndossier version
The version is displayed using:
opndossier version
Changelog Generation#
The project uses git-cliff with a custom cliff.toml configuration:
Commit Categories#
Commits are automatically categorized based on conventional commit prefixes:
- Features:
feat:commits - Bug Fixes:
fix:commits - Security:
fix(security):commits or security-related changes - Documentation:
doc:commits - Performance:
perf:commits - Refactor:
refactor:commits - Styling:
style:commits - Testing:
test:commits - Miscellaneous:
chore:andci:commits - Revert:
revert:commits
Commit Message Format#
Follow conventional commits:
type(scope): description
[optional body]
[optional footer]
Examples:
feat(auth): add OAuth2 supportfix(parser): handle malformed XML gracefullydocs: update installation instructions
Troubleshooting#
Common Issues#
-
GoReleaser Configuration Errors:
just check-goreleaser -
Missing git-cliff:
mise install # Installs all tools via mise.toml -
Missing Security Tools:
just install-security-tools # Install gosec, cyclonedx-gomod -
Build Failures:
- Check Go version compatibility (requires Go 1.26+)
- Ensure all tests pass:
just test - Verify dependencies:
go mod tidy
-
Docker Login Issues:
- Verify GITHUB_TOKEN permissions
- Check container registry access
- Ensure you're logged in:
docker login ghcr.io - Test Docker access:
docker pull ghcr.io/evilbit-labs/opndossier:latest
-
Security Scan Failures:
- Check for high-severity vulnerabilities in dependencies
- Review SBOM for unexpected dependencies
- Verify license compliance with FOSSA
Release Validation#
After a release, verify:
-
GitHub Release Page:
- Release notes are generated correctly
- All binary artifacts are attached
- Checksums file is present
- SBOM files are included
- THIRD_PARTY_NOTICES is included in archives and packages
- SLSA provenance attestation is attached
-
Docker Images:
docker pull ghcr.io/evilbit-labs/opndossier:latest docker run --rm ghcr.io/evilbit-labs/opndossier:latest version -
Binary Downloads:
- Test download and execution of binaries for your platform
- Verify version information is correct
-
Security Verification:
# Verify checksums sha256sum -c opnDossier_checksums.txt # Verify SLSA provenance slsa-verifier verify-artifact \ --provenance-path opnDossier-v1.0.0.intoto.jsonl \ --source-uri github.com/EvilBit-Labs/opnDossier \ opnDossier_checksums.txt
Release Schedule#
opnDossier follows these release practices:
- Patch Releases: As needed for critical bug fixes
- Minor Releases: When new features are ready and tested
- Major Releases: For breaking changes or significant milestones
- Pre-releases: Beta and RC versions for testing before major releases
Security Considerations#
- All releases are signed and checksummed
- Docker images include security labels and provenance information
- macOS binaries can be notarized when certificates are configured
- Dependencies are automatically updated via Dependabot
- CodeQL analysis runs on all releases
- SLSA Level 3 provenance provides build integrity verification
- Cosign signatures ensure artifact authenticity
- Comprehensive vulnerability scanning with Grype and Snyk
- License compliance verified with FOSSA
- Third-party license notices provide transparency for all dependencies
Post-Release Tasks#
After a successful release:
- Update Documentation: Ensure docs reflect new features
- Close Milestones: Close the GitHub milestone for the release
- Announce Release: Update relevant channels about the new version
- Monitor Issues: Watch for any issues reported with the new release
- Security Monitoring: Monitor for any security issues in dependencies
Rollback Procedure#
If a release has critical issues:
- Create Hotfix: Fix the issue in a new patch release
- Update GitHub Release: Mark problematic release as pre-release if needed
- Docker Images: Latest tag will point to the new fixed version
- Communication: Notify users about the issue and fix
- Security Assessment: Re-run security scans to ensure no new vulnerabilities
For questions about the release process, please refer to the project's https://github.com/EvilBit-Labs/opnDossier/blob/main/CONTRIBUTING.md or open an issue.