Skip to content

feat: [IANDT-237] add active contributor emitter - #697

Open
jonnyowenpowell wants to merge 1 commit into
mainfrom
feat/IANDT-237-contributor-billing
Open

feat: [IANDT-237] add active contributor emitter#697
jonnyowenpowell wants to merge 1 commit into
mainfrom
feat/IANDT-237-contributor-billing

Conversation

@jonnyowenpowell

@jonnyowenpowell jonnyowenpowell commented Aug 12, 2026

Copy link
Copy Markdown

Description

This PR adds an API client for the public submit contributing developers endpoint served by the entitlements-service (pkg/apiclients/contributors_ingest), a helper function to collect contributor data (contributors.go) from the Git repository the command is being run in, and an emitter object (billing.go) which ties the two together, exposing an Emit function to perform the work.

Checklist

  • Tests added and all succeed (make test)
  • Regenerated mocks, etc. (make generate)
  • Linted (make lint)
  • Test your changes work for the CLI
    1. Clone / pull the latest CLI main.
    2. Run go get github.com/snyk/go-application-framework@YOUR_LATEST_GAF_COMMIT in the cliv2 directory.
      • Tip: for local testing, you can uncomment the line near the bottom of the CLI's go.mod to point to your local GAF code.
    3. Run go mod tidy in the cliv2 directory.
    4. Run the CLI tests and do any required manual testing.
    5. Open a PR in the CLI repo now with the go.mod and go.sum changes.
    • Once this PR is merged, repeat these steps, but pointing to the latest GAF commit on main and update your CLI PR.

@snyk-io

snyk-io Bot commented Aug 12, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues
Secrets 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@snyk-io

snyk-io Bot commented Aug 12, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@jonnyowenpowell
jonnyowenpowell force-pushed the feat/IANDT-237-contributor-billing branch from dfe3785 to 3a994a8 Compare August 12, 2026 13:42
Comment thread internal/contributorbilling/contributors.go
Comment thread pkg/apiclients/contributors_ingest/ingest.go Outdated
@jonnyowenpowell
jonnyowenpowell force-pushed the feat/IANDT-237-contributor-billing branch 2 times, most recently from 1894254 to 8796cbc Compare August 13, 2026 11:08
Comment thread internal/contributorbilling/contributors.go Outdated
@jonnyowenpowell jonnyowenpowell changed the title feat: add active contributor emitter feat: [IANDT-237] add active contributor emitter Aug 13, 2026
@jonnyowenpowell
jonnyowenpowell marked this pull request as ready for review August 13, 2026 11:12
@jonnyowenpowell
jonnyowenpowell requested review from a team as code owners August 13, 2026 11:12

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8796cbc. Configure here.

Comment thread internal/contributorbilling/contributors.go
Comment thread internal/contributorbilling/contributors.go
@snyk-pr-review-bot

This comment has been minimized.

@jonnyowenpowell

Copy link
Copy Markdown
Author

Remember to assess bringing back capability check

@jonnyowenpowell
jonnyowenpowell force-pushed the feat/IANDT-237-contributor-billing branch from 8796cbc to daf8020 Compare August 14, 2026 09:59
@jonnyowenpowell

Copy link
Copy Markdown
Author

Remember to assess bringing back capability check

Done, this doesn't belong here - and will instead be checked in the code that may call Emit.

@snyk-pr-review-bot

Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Nested Retry Storm 🔴 [critical]

The retrying function wraps an existing http.Client with a new RetryMiddleware, but the base client received from the engine (via billing.go) already contains the framework's default retry middleware. This creates a nested retry structure where each attempt of the outer 3-attempt cycle triggers a full internal retry cycle (typically another 3 attempts), potentially resulting in 9 requests per failure. Furthermore, since the inner middleware still uses the framework's slower default backoff (5s), the outer layer's 1s override is ignored during the inner retry phase, failing to meet the tight 10s budget.

func retrying(base *http.Client, logger *zerolog.Logger) *http.Client {
	client := &http.Client{}
	transport := http.DefaultTransport
	if base != nil {
		*client = *base
		if base.Transport != nil {
			transport = base.Transport
		}
	}
	if logger == nil {
		nop := zerolog.Nop()
		logger = &nop
	}

	// The retry middleware reads only these two keys, so the policy is owned here
	// rather than by whatever configuration the caller happens to hold.
	config := configuration.NewWithOpts()
	config.Set(middleware.ConfigurationKeyRequestAttempts, requestAttempts)

	client.Transport = middleware.NewRetryMiddleware(
		config, logger, transport, middleware.WithRetryInterval(retryInterval),
	)

	return client
}
Risky Early-Stop Logic 🟠 [major]

The logic to stop git log iteration early assumes that a 'commit date <= authored date' relationship exists and makes the cutoff safe. In Git, the relationship is typically the inverse: AuthorDate <= CommitterDate. If the developer's stated assumption holds, stopping on an old CommitterDate is actually unsafe because a newer AuthorDate could still fall within the 90-day window. While the code is likely safe for standard Git usage (where Committer is the upper bound), the contradiction between the comment and the code's safety requirements suggests a logic error that could lead to under-counting contributors if clocks are skewed or non-standard Git workflows are used.

err = iter.ForEach(func(commit *object.Commit) error {
	if commit.Committer.When.Before(since) {
		return storer.ErrStop
	}
📚 Repository Context Analyzed

This review considered 49 relevant code sections from 15 files (average relevance: 0.96)

🤖 Repository instructions applied (from AGENTS.md)

@@ -0,0 +1,174 @@
// Package contributors_ingest is a client for the Contributing Devs ingest API,
// which records the git contributors associated with a Snyk entity for billing.
package contributors_ingest

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this package to internal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants