Thank you for your interest in contributing to the Portkey Terraform Provider! We welcome contributions from the community.
By participating in this project, you agree to maintain a respectful and collaborative environment.
- Search First: Check if the issue already exists in the issue tracker
- Provide Details: Include as much information as possible:
- Provider version
- Terraform version
- Go version (if building from source)
- Steps to reproduce
- Expected vs actual behavior
- Relevant configuration files (sanitized)
- Error messages and logs
- Open an issue with the
enhancementlabel - Describe the use case and benefits
- Provide examples of how it would work
- Fork and Clone
git clone https://github.com/YOUR-USERNAME/terraform
cd terraform-
Create a Branch
git checkout -b feature/your-feature-name
-
Make Changes
- Write clear, maintainable code
- Follow Go best practices
- Add tests for new functionality
- Update documentation
-
Test Your Changes
# Run unit tests go test ./... # Build the provider make build # Install locally and test make install
-
Commit and Push
git add . git commit -m "feat: add new feature" git push origin feature/your-feature-name
-
Open Pull Request
- Provide a clear description of changes
- Reference any related issues
- Ensure CI checks pass
- Go 1.21 or later
- Terraform 1.0 or later
- Portkey Admin API key for testing
# Clone the repository
git clone https://github.com/Portkey-AI/terraform-provider-portkey
cd terraform
# Install dependencies
go mod download
# Build the provider
make build
# Install locally
make install# Unit tests
go test ./...
# Acceptance tests (requires valid API key)
export PORTKEY_API_KEY="your-admin-api-key"
make testacc- Follow standard Go formatting:
gofmtandgo vet - Use meaningful variable and function names
- Add comments for complex logic
- Keep functions focused and concise
Follow Conventional Commits:
feat:New featurefix:Bug fixdocs:Documentation changestest:Test additions or changesrefactor:Code refactoringchore:Maintenance tasks
Examples:
feat: add virtual_key resource
fix: handle nil pointer in workspace update
docs: update installation instructions
terraform/
├── internal/
│ ├── client/ # API client implementation
│ └── provider/ # Terraform resources and data sources
├── examples/ # Usage examples
├── docs/ # Documentation
└── main.go # Provider entry point
- Create
{resource_name}_resource.goininternal/provider/ - Implement the resource interface:
- Schema definition
- Create, Read, Update, Delete operations
- Import functionality
- Register the resource in
provider.go - Add tests
- Update documentation
- Create
{resource_name}_data_source.goininternal/provider/ - Implement the data source interface:
- Schema definition
- Read operation
- Register the data source in
provider.go - Add tests
- Update documentation
- Test individual functions and methods
- Mock external dependencies
- Cover edge cases and error conditions
- Test full resource lifecycle (Create, Read, Update, Delete)
- Test import functionality
- Use unique resource names to avoid conflicts
- Clean up resources after tests
Example:
func TestAccWorkspaceResource(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testAccWorkspaceConfig("test-name"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("portkey_workspace.test", "name", "test-name"),
),
},
// Import testing
{
ResourceName: "portkey_workspace.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}- Update README.md for significant changes
- Add examples for new resources
- Document breaking changes
- Keep CHANGELOG.md updated
This section outlines the standard process for reviewing, merging, and releasing PRs in this repository.
# View open PRs
gh pr list
# Checkout the PR locally
gh pr checkout <PR-number>CHECKPOINT 1 - Understand the PR:
- Read the PR description and linked issues
- Ask yourself: What problem does this solve? Is this functionality we need?
- For new features: verify we don't already cover this functionality elsewhere
Run these checks locally:
# Build the provider
go build ./...
# Run static analysis
go vet ./...
gofmt -d .
# Run linter (note: may have known issues with golangci-lint v2)
golangci-lint run
# Run the full test suite
make testaccCHECKPOINT 2 - Evaluate code quality against these criteria:
- Tests cover the full CRUD lifecycle (Create, Read, Update, Delete)
- Tests verify import functionality works
- Tests check actual attribute values, not just existence
- Tests cover edge cases (updates, deletions, error conditions)
- Tests are meaningful, not just "passes but tests nothing"
Example of a good test check:
resource.TestCheckResourceAttr("portkey_resource.test", "name", "expected-value"),Example of malicious compliance (avoid):
// Only checks attribute exists, not its value
resource.TestCheckResourceAttrSet("portkey_resource.test", "id"),- Changes are additive (new files) vs. modifying existing logic
- If modifying existing code: understand why and verify no regressions
- Check
provider.gochanges - should only add new registrations - Verify no unrelated changes snuck in
- File naming follows pattern:
{resource}_resource.go,{resource}_data_source.go - Schema definitions match existing resources (descriptions, validators, plan modifiers)
- Error handling is consistent with other resources
- API client methods follow existing patterns in
client/client.go
- Resource docs exist in
docs/resources/ordocs/data-sources/ - Examples are provided
- RESOURCE_MATRIX.md is updated (if applicable)
If changes are needed:
gh pr review <PR-number> --request-changes --body "Your detailed feedback"Be specific about:
- What needs to change and why
- Provide code examples when helpful
- Reference existing code patterns to follow
If PR is good:
gh pr review <PR-number> --approve --body "Your approval message"CHECKPOINT 3 - Before approving, verify:
- CI checks are passing (or failures are pre-existing/unrelated)
- You've run tests locally
- Code compiles without errors
- You understand what the code does
# Merge the PR
gh pr merge <PR-number> --merge
# Pull changes to local main
git checkout main && git pullEdit CHANGELOG.md:
- Add entry under
[Unreleased]describing what was added/changed/fixed - Follow the existing format and categorization (Added, Changed, Fixed, etc.)
When ready to release (can batch multiple PRs):
# 1. Update CHANGELOG.md
# - Change [Unreleased] to [X.Y.Z] - YYYY-MM-DD
# - Add new empty [Unreleased] section
# - Update comparison links at bottom
# 2. Commit and push
git add CHANGELOG.md
git commit -m "chore: update CHANGELOG for vX.Y.Z"
git push origin main
# 3. Create and push tag
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z
# 4. Monitor release
gh run watch $(gh run list --workflow=release.yml --limit 1 --json databaseId -q '.[0].databaseId') --exit-status
# 5. Verify
gh release view vX.Y.ZThe golangci-lint configuration may have compatibility issues with certain Go versions. If lint fails in CI but the PR code is correct:
- Verify the lint errors are pre-existing (not introduced by the PR)
- Check if errors are in files not touched by the PR
- The lint config (
.golangci.yml) may need updates when Go version changes
If rebasing a PR branch and git push --force-with-lease fails with "stale info":
git push --force # Use with caution, only on PR branchesIf CI fails intermittently:
- Re-run the workflow:
gh run rerun <run-id> - Check if it's a timing/race condition in tests
- Check if it's an API rate limit issue
If a contributor needs help making changes and "Allow edits from maintainers" is enabled:
# Add their fork as remote
git remote add contributor-fork https://github.com/CONTRIBUTOR/terraform-provider-portkey.git
# Push fixes to their branch
git push contributor-fork HEAD:their-branch-nameEvery PR review is a learning opportunity. After each review session, take a moment to reflect:
- Did you learn a new pattern or technique from the contributor's code?
- Did you discover an edge case you hadn't considered before?
- Did the discussion reveal gaps in documentation or testing patterns?
- Could this PR's approach improve other parts of the codebase?
Good feedback flows both ways. Stay curious, ask questions when something is unclear, and remember that even experienced contributors can learn something new from every code review.
- Merge all PRs for the release
- Verify CI passes on main branch
# 1. Checkout and pull latest main
git checkout main && git pull
# 2. Update CHANGELOG.md
# - Change [Unreleased] to [X.Y.Z] with today's date
# - Add new empty [Unreleased] section
# - Update comparison links at bottom of file
# 3. Commit changelog
git add CHANGELOG.md
git commit -m "chore: update CHANGELOG for vX.Y.Z"
git push origin main
# 4. Create and push tag (triggers release workflow)
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z
# 5. Monitor release workflow
gh run list --workflow=release.yml --limit 1
gh run watch <run-id> --exit-status
# 6. Verify release
gh release view vX.Y.ZFollow Semantic Versioning:
- MAJOR (1.0.0): Breaking changes
- MINOR (0.X.0): New features, backwards compatible
- PATCH (0.0.X): Bug fixes, backwards compatible
The GitHub Action (.github/workflows/release.yml) automatically:
- Builds binaries for all platforms (darwin, linux, windows)
- Signs artifacts with GPG
- Creates GitHub release with changelog
- Publishes to Terraform Registry
- Questions: Open a GitHub Discussion
- Bugs: File an issue
- Chat: Join the Portkey Discord
By contributing, you agree that your contributions will be licensed under the same license as the project (Mozilla Public License 2.0).
Your contributions help make this project better for everyone! 🙏