Not all new PRs will be merged in
It's recommended to check with the owner first (e.g. raise an issue) to discuss a new feature before developing, to ensure your hard efforts don't go to waste.
PRs to fix bugs and issues are almost always welcome 🙏 please ensure you write tests as well.
The following types of PRs will not be accepted:
- Significant refactors take a lot of time to understand and can have all sorts of unintended side effects. If you think there's a better way to do things (that requires significant changes) raise an issue for discussion first :)
- Release pipeline PRs are a security risk - it's too easy for a serious vulnerability to sneak in (either intended or not). If there is a new cool way of releasing things, raise an issue for discussion first - it will need to be gone over with a fine tooth comb.
- Version bumps are handled by dependabot, the bot will auto-raise PRs and they will be regularly merged in.
- New release platforms At this stage, yq is not going to maintain any other release platforms other than GitHub and Docker - that said, I'm more than happy to put in other community maintained methods in the README for visibility ❤️
- Install Golang (version 1.24.0 or later)
- Run
scripts/devtools.shto install required development tools:- golangci-lint for code linting
- gosec for security analysis
- Run
make [local] vendorto install vendor dependencies - Run
make [local] testto ensure you can run the existing tests
- Write unit tests first - Changes will not be accepted without corresponding unit tests (see Testing section below)
- Make your code changes
- Run tests and linting:
make [local] test(this runs formatting, linting, security checks, and tests) - Create your PR and get kudos! :)
- Use
make [local] <command>for local development (runs in Docker container) - Use
make <command>for CI/CD environments - Common commands:
make [local] vendor- Install dependenciesmake [local] test- Run all checks and testsmake [local] build- Build the yq binarymake [local] format- Format codemake [local] check- Run linting and security checks
The project uses strict linting rules defined in .golangci.yml. All code must pass:
- Code formatting: gofmt, goimports, gci
- Linting: revive, errorlint, gosec, misspell, and others
- Security checks: gosec security analysis
- Spelling checks: misspell detection
Run make [local] check to verify your code meets all quality standards.
- Follow standard Go conventions
- Use meaningful variable names
- Add comments for public functions and complex logic
- Keep functions focused and reasonably sized
- Use the project's existing patterns and conventions
Tests in yq use the expressionScenario pattern. Each test scenario includes:
expression: The yq expression to testdocument: Input YAML/JSON (optional)expected: Expected outputskipDoc: Whether to skip documentation generation
- Find the appropriate test file (e.g.,
operator_add_test.gofor addition operations) - Add your test scenario to the
*OperatorScenariosslice - Run the specific test:
go test -run TestAddOperatorScenarios(replace with appropriate test name) - Verify documentation generation (see Documentation section)
var addOperatorScenarios = []expressionScenario{
{
skipDoc: true,
expression: `"foo" + "bar"`,
expected: []string{
"D0, P[], (!!str)::foobar\n",
},
},
{
document: "apples: 3",
expression: `.apples + 3`,
expected: []string{
"D0, P[apples], (!!int)::6\n",
},
},
}- All tests:
make [local] test - Specific test:
go test -run TestName - With coverage:
make [local] cover
The project uses a documentation system that combines static headers with dynamically generated content from tests.
- Static headers are defined in
pkg/yqlib/doc/operators/headers/*.md - Dynamic content is generated from test scenarios in
*_test.gofiles - Generated docs are created in
pkg/yqlib/doc/*.mdby concatenating headers with test-generated content - Documentation is synced to the gitbook branch for the website
Most operator documentation is generated from tests. To update:
- Find the test file (e.g.,
operator_add_test.go) - Update test scenarios - each
expressionScenariowithskipDoc: falsebecomes documentation - Run the test to regenerate docs:
cd pkg/yqlib go test -run TestAddOperatorScenarios
- Verify the generated documentation in
pkg/yqlib/doc/add.md - Create a PR with your changes
If documentation exists only in headers/*.md files:
- Update the header file directly (e.g.,
pkg/yqlib/doc/operators/headers/add.md) - Create a PR with your changes
For documentation not in the master branch:
- Check the gitbook branch for additional pages
- Update the
*.mdfiles directly - Create a PR to the gitbook branch
- Write clear, concise examples in test scenarios
- Use meaningful variable names in examples
- Include edge cases and error conditions
- Test your documentation changes by running the specific test
- Verify generated output matches expectations
Note: PRs with small changes (e.g. minor typos) may not be merged (see https://joel.net/how-one-guy-ruined-hacktoberfest2020-drama).
- Problem:
makecommands fail with Docker errors - Solution: Ensure Docker or Podman is running and accessible
- Alternative: Use
make local <command>to run in containers
- Problem: Build fails with Go version errors
- Solution: Ensure you have Go 1.24.0 or later installed
- Check: Run
go versionto verify
- Problem:
make vendorfails or dependencies are outdated - Solution:
go mod tidy make [local] vendor
- Problem:
make checkfails with linting errors - Solution:
make [local] format # Auto-fix formatting # Manually fix remaining linting issues make [local] check # Verify fixes
-
Problem: Tests fail locally but pass in CI
-
Solution:
make [local] test # Run in Docker container
-
Problem: Tests fail with a VCS error:
error obtaining VCS status: exit status 128 Use -buildvcs=false to disable VCS stamping. -
Solution: Git security mechanisms prevent Golang from detecting the Git details inside the container; either build with the
localoption, or pass GOFLAGS to disable Golang buildvcs behaviour.make local test # OR make test GOFLAGS='-buildvcs=true'
- Problem: Generated docs don't update after test changes
- Solution:
cd pkg/yqlib go test -run TestSpecificOperatorScenarios # Check if generated file updated in pkg/yqlib/doc/
- Check existing issues: Search GitHub issues for similar problems
- Create an issue: If you can't find a solution, create a detailed issue
- Ask questions: Use GitHub Discussions for general questions
- Join the community: Check the project's community channels