Skip to content

[GitHub API] Implement a reusable read-only API client boundary for Actions collection #40

Description

@Dyu20705

Problem statement

RunSift's optional GitHub Actions collector needs a small, reusable GitHub API boundary instead of scattering HTTP/API behavior across run selection and evidence-download code.

This issue provides the transport and reliability layer used by #7 and #8 while keeping the analyzer itself fully offline and deterministic.

The integration is read-only by construction. It must not expose GitHub mutation operations.

Goals

  • centralize GitHub REST API request behavior behind a narrow adapter;
  • make pagination, rate limits, retries, timeouts, API-version headers, and errors consistent;
  • keep authentication handling compatible with the least-privilege contract in [GitHub Actions] Implement least-privilege authentication and workflow-run selection #7;
  • make all API behavior testable without live GitHub requests;
  • provide reusable primitives for workflow-run, job, and evidence collection without coupling domain analysis to GitHub-specific response shapes.

Checklist

  • Define a narrow GitHub API client/transport interface owned by the collection adapter
  • Keep GitHub-specific DTOs at the adapter boundary and normalize domain inputs through [Core] Implement versioned input, evidence, and output schemas #34 schemas
  • Send an explicit supported GitHub REST API version header and appropriate Accept/User-Agent headers
  • Implement deterministic pagination with configurable hard page/item limits
  • Parse and surface primary rate-limit information where available
  • Handle secondary/abuse rate limiting and Retry-After without aggressive polling
  • Implement bounded exponential backoff with jitter only for retry-safe read requests
  • Do not retry persistent authentication, permission, validation, or ordinary not-found failures
  • Apply explicit connect/read/request timeouts and cancellation boundaries
  • Classify failures into actionable categories: authentication, permission, not found, rate limited, timeout/network, upstream/server, malformed/unexpected API response
  • Ensure token values and sensitive headers are redacted from exceptions, logs, snapshots, and debug output
  • Support dependency injection or an equivalent seam so [GitHub Actions] Implement least-privilege authentication and workflow-run selection #7/[GitHub Actions] Fetch bounded failed-job evidence into normalized local bundles #8 tests can use deterministic fake/mock transports
  • Add unit tests for pagination, timeout, rate-limit, retry, malformed-response, and redaction behavior
  • Add contract fixtures for representative GitHub API responses without requiring network access
  • Document the allowed read-only endpoint surface used by RunSift

Read-only endpoint boundary

Initial client capabilities should be limited to the endpoint families required by #7/#8, such as:

  • repository/workflow-run metadata needed for deterministic run selection;
  • workflow jobs for an explicitly selected run/attempt;
  • log/evidence retrieval needed to build the normalized local bundle.

Any new endpoint family requires an explicit product need and tests. Mutation endpoints such as rerun, dispatch, check creation, comments, repository changes, or workflow modification are out of scope.

Reliability requirements

  • Retries are bounded by attempt count and elapsed-time budget.
  • Pagination has explicit maximum pages/items so an unexpected repository cannot cause unbounded collection.
  • Rate-limit handling must prefer GitHub-provided reset/retry metadata when available rather than tight polling.
  • Retry behavior must remain deterministic in tests by injecting clock/sleep/jitter behavior where necessary.
  • Partial or malformed API responses must never be silently treated as complete evidence.

Acceptance criteria

  • [GitHub Actions] Implement least-privilege authentication and workflow-run selection #7 can use the client to enumerate/select workflow runs without implementing its own HTTP/retry/pagination logic
  • [GitHub Actions] Fetch bounded failed-job evidence into normalized local bundles #8 can reuse the same client boundary for jobs/evidence retrieval
  • Live GitHub access is not required by the normal unit/integration test suite
  • A simulated multi-page response is collected deterministically within configured bounds
  • Simulated 401/403/404/rate-limit/5xx/timeout paths map to distinct actionable errors
  • Retry tests prove that persistent auth/permission failures are not retried
  • Tokens and authorization headers cannot appear in emitted diagnostics or stored fixtures
  • No GitHub write endpoint is exposed by the adapter
  • Offline fixture/local analysis remains completely independent of this client

Dependencies / relationships

Non-goals

  • GitHub App installation or webhooks
  • repository mutation or automatic remediation
  • background polling/service infrastructure
  • multi-repository analytics
  • replacing deterministic local fixtures with live API tests
  • adding a general-purpose GitHub SDK abstraction beyond RunSift's collection needs

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:github-actionsGitHub Actions API, workflow runs, jobs, and logsarea:infraCI/CD, packaging, release, and developer toolingarea:securityAuthentication, permissions, secret safety, and secure behaviorpriority:highImportant work planned for the current milestonesize:mMedium estimatetype:featureUser-facing product capability

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions