Skip to content

Contributing Guide

This document covers contributing guidelines, development workflow, and code style for QPKI.

  • Go 1.25 or later
  • Git
  • Make (optional, for convenience commands)
  • Java 17+ (for BouncyCastle cross-tests)
  • Maven 3.6+ (for BouncyCastle cross-tests)
Terminal window
git clone https://github.com/remiblancher/qpki.git
cd qpki
go build -o qpki ./cmd/qpki
go test -v ./...
go test -v -race ./...
TypePatternExample
Featurefeature/<description>feature/add-ocsp-support
Bug fixfix/<description>fix/crl-parsing-error
Documentationdocs/<description>docs/update-readme
Refactoringrefactor/<description>refactor/crypto-package

Follow conventional commit format:

<type>(<scope>): <description>
[optional body]
[optional footer]

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation only
  • test: Adding tests
  • refactor: Code refactoring
  • chore: Maintenance tasks

Examples:

feat(ca): add OCSP responder support
fix(crypto): handle nil public key in SubjectKeyID
docs(readme): update installation instructions
  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: go test -v -race ./...
  5. Run linter: golangci-lint run
  6. Push to your fork
  7. Create a Pull Request

Follow standard Go conventions:

We use golangci-lint:

Terminal window
golangci-lint run

Enabled linters:

  • errcheck, gosimple, govet, ineffassign, staticcheck, unused, gofmt, goimports
  • All exported functions must have doc comments
  • Doc comments should start with the function name
  • Include examples for complex functions
// GenerateKey creates a new cryptographic key pair.
//
// Supported algorithms: ecdsa-p256, ecdsa-p384, ed25519, rsa-2048,
// ml-dsa-44, ml-dsa-65, ml-dsa-87.
func GenerateKey(alg AlgorithmID) (Signer, error) {
// ...
}
  1. Add algorithm constant to internal/crypto/algorithms.go
  2. Add OID to internal/x509util/oids.go
  3. Implement key generation in internal/crypto/keygen.go
  4. Add signing support in internal/crypto/software.go
  5. Add tests for all operations
  6. Update documentation
  1. Create new file in internal/profile/
  2. Implement Profile interface
  3. Register in profile registry
  4. Add CLI support in cmd/qpki/issue.go
  5. Add tests
  6. Update relevant documentation (CA.md, CREDENTIALS.md, CLI.md)
  1. Create new file in cmd/qpki/
  2. Define cobra command with flags
  3. Register in init() function
  4. Add tests
  5. Update relevant documentation (CLI.md)
  • Never log sensitive data (private keys, passphrases)
  • Use constant-time comparisons for secrets
  • Validate all inputs
  • Handle errors properly (don’t ignore them)

If you discover a security vulnerability:

  1. Do not open a public issue
  2. Email the maintainers directly
  3. Include detailed reproduction steps
  4. Allow time for a fix before disclosure

We use Semantic Versioning:

  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes (backward compatible)
  1. Update version in code
  2. Update CHANGELOG.md
  3. Run full test suite
  4. Create annotated tag: git tag -a v1.0.0 -m "Release v1.0.0"
  5. Push tag: git push origin v1.0.0
  6. GitHub Actions builds and releases

Dependabot keeps dependencies up to date automatically.

  • Go modules: Weekly scan of go.mod
  • GitHub Actions: Weekly scan of workflows
  • PRs labeled dependencies + go or ci
Terminal window
go get -u ./...
go mod tidy
  • Be respectful and inclusive
  • Accept constructive criticism
  • Focus on what is best for the community
  • Show empathy towards others
  • Harassment or discrimination
  • Trolling or personal attacks
  • Publishing others’ private information
  • Other unprofessional conduct

Contributions are welcome.

By contributing to this project, you agree to the Contributor License Agreement (CLA). See CLA.md.

By contributing, you agree that your contributions will be licensed under the Apache License 2.0.

This project uses AI-assisted development. See AI_USAGE.md for details on how AI tools are used in this project.