devlake

package
v1.149.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package devlake provides a Go client for the DevLake Webhook API.

It solves the problem of sending deployment and incident lifecycle events from Go services to DevLake in a consistent, validated, and retry-capable way.

The package includes typed request models for deployments, deployment commits, incident creation, and incident close operations, with validation tags aligned to expected webhook payload constraints.

Top features:

- strongly typed request payloads for deployment and incident webhook endpoints - client helpers for SendDeployment, SendIncident, and SendIncidentClose - request validation before network calls using field/tag-based constraints - health check support for validating API reachability - configurable timeouts, retry attempts, and custom HTTP client injection - bearer-token authenticated JSON requests with contextual error wrapping

Benefits:

  • reduces boilerplate for posting DevLake webhook events from application code
  • catches malformed payloads early, before expensive remote calls
  • improves reliability under transient failures via retrier integration
  • keeps integration logic centralized and easy to maintain across services

This package is based on the DevLake Webhook API documentation available at: https://devlake.apache.org/docs/Plugins/webhook/

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidAddress is returned by New when the DevLake address is missing,
	// unparseable, or lacks a scheme or host.
	ErrInvalidAddress = errors.New("devlake: invalid address")

	// ErrEmptyAPIKey is returned by New when the API key is empty.
	ErrEmptyAPIKey = errors.New("devlake: api key is empty")

	// ErrInvalidRetryConfig is returned by New when the retry options are invalid.
	ErrInvalidRetryConfig = errors.New("devlake: invalid retry configuration")

	// ErrNilRequest is returned by the Send methods when the request is nil.
	ErrNilRequest = errors.New("devlake: request must not be nil")
)

Exported sentinel errors returned by this package. Match them with errors.Is.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client sends deployment and incident webhook events to DevLake.

func New

func New(addr, apiKey string, opts ...Option) (*Client, error)

New creates a DevLake webhook client with validation and retry defaults.

It solves repetitive integration setup by centralizing base URL parsing, bearer-token authentication, payload validation, endpoint URL construction, and default network timeouts/retry policy.

Example addr: "https://app.devlake.invalid".

func (*Client) HealthCheck

func (c *Client) HealthCheck(ctx context.Context) (err error)

HealthCheck verifies that the DevLake API endpoint is reachable and healthy.

The request uses pingTimeout and returns an error for transport failures, timeout failures, or non-200 responses.

func (*Client) SendDeployment

func (c *Client) SendDeployment(ctx context.Context, request *DeploymentRequest) error

SendDeployment submits a deployment event to DevLake.

It validates request and posts it to the deployment webhook endpoint scoped by ConnectionID.

func (*Client) SendIncident

func (c *Client) SendIncident(ctx context.Context, request *IncidentRequest) error

SendIncident submits an incident event to DevLake.

It validates request and posts it to the incident webhook endpoint scoped by ConnectionID.

func (*Client) SendIncidentClose

func (c *Client) SendIncidentClose(ctx context.Context, request *IncidentRequestClose) error

SendIncidentClose sends an incident-close event for an existing incident.

It validates the close request and calls the dedicated close endpoint using ConnectionID and IssueKey.

type DeploymentCommitsRequest

type DeploymentCommitsRequest struct {
	// DisplayTitle is a readable title for the deployment to this repo.
	DisplayTitle string `json:"displayTitle,omitempty" validate:"omitempty,max=255"`

	// RepoID is the repo ID.
	RepoID string `json:"repoID,omitempty" validate:"omitempty,max=255"`

	// RepoURL is the repo URL of the deployment commit.
	// If there is a row in the domain layer table repos where repos.url equals repo_url,
	// the repoId will be filled with repos.id.
	RepoURL string `json:"repoUrl" validate:"required,url"`

	// Name is the name of this commit.
	Name string `json:"name,omitempty" validate:"omitempty,max=255"`

	// RefName is the branch/tag to deploy.
	RefName string `json:"refName,omitempty" validate:"omitempty,max=255"`

	// CommitSha is the commit SHA that triggers the deploy in this repo.
	CommitSha string `json:"commitSha" validate:"required,min=40,max=255"`

	// CommitMsg is the commit SHA of the deployment commit message.
	CommitMsg string `json:"commitMsg,omitempty" validate:"omitempty,max=65536"`

	// Result is the result of the deploy to this repo. The default value is 'SUCCESS'.
	Result string `json:"result,omitempty" validate:"omitempty,max=50"`

	// Status is the commit status.
	Status string `json:"status,omitempty" validate:"omitempty,max=50"`

	// CreatedDate is the creation time of this commit.
	// E.g. 2020-01-01T12:00:00+00:00.
	CreatedDate *time.Time `json:"createdDate,omitempty" validate:"omitempty"`

	// StartedDate is the start time of the deploy to this repo.
	// E.g. 2020-01-01T12:00:00+00:00.
	StartedDate *time.Time `json:"startedDate" validate:"required"`

	// FinishedDate is the end time of the deploy to this repo.
	// E.g. 2020-01-01T12:00:00+00:00.
	FinishedDate *time.Time `json:"finishedDate" validate:"required"`
}

DeploymentCommitsRequest defines a deploymentCommits request item.

type DeploymentRequest

type DeploymentRequest struct {
	// ConnectionID is the ID of the DevLake connection where to send the deployment request.
	ConnectionID uint64 `json:"-" validate:"required"`

	// ID is the unique ID of table cicd_deployments.
	ID string `json:"id" validate:"required,max=255"`

	// DisplayTitle is a readable title for the deployment to this repo.
	DisplayTitle string `json:"displayTitle,omitempty" validate:"omitempty,max=255"`

	// Result is the deployment result, one of the values : SUCCESS, FAILURE, ABORT, MANUAL.
	// The default value is SUCCESS.
	Result string `json:"result,omitempty" validate:"omitempty,oneof=SUCCESS FAILURE ABORT MANUAL"`

	// Environment is the environment this deployment happens.
	// For example: PRODUCTION, STAGING, TESTING, DEVELOPMENT.
	// The default value is PRODUCTION.
	Environment string `json:"environment,omitempty" validate:"omitempty,oneof=PRODUCTION STAGING TESTING DEVELOPMENT"`

	// Name is the name of this deployment.
	Name string `json:"name,omitempty" validate:"omitempty,max=255"`

	// URL is the deployment URL.
	URL string `json:"url,omitempty" validate:"omitempty,url"`

	// CreatedDate is the time this deploy pipeline starts.
	// E.g. 2020-01-01T12:00:00+00:00.
	CreatedDate *time.Time `json:"createdDate,omitempty" validate:"omitempty"`

	// StartedDate is the time when the first deploy to a certain repo starts.
	// E.g. 2020-01-01T12:00:00+00:00.
	StartedDate *time.Time `json:"startedDate" validate:"required"`

	// FinishedDate is the time when the last deploy to a certain repo ends.
	// E.g. 2020-01-01T12:00:00+00:00.
	FinishedDate *time.Time `json:"finishedDate" validate:"required"`

	// DeploymentCommits is used for multiple commits in one deployment.
	DeploymentCommits []DeploymentCommitsRequest `json:"deploymentCommits,omitempty" validate:"omitempty,dive"`
}

DeploymentRequest defines the request to register a Deployment.

type HTTPClient

type HTTPClient interface {
	// Do executes the HTTP request.
	Do(req *http.Request) (*http.Response, error)
}

HTTPClient is the minimal HTTP transport contract used by Client.

type IncidentRequest

type IncidentRequest struct {
	// ConnectionID is the ID of the DevLake connection where to send the incident request.
	ConnectionID uint64 `json:"-" validate:"required"`

	// URL is the Issue URL.
	URL string `json:"url,omitempty" validate:"omitempty,url"`

	// IssueKey is the Issue key. It needs to be unique in a connection.
	IssueKey string `json:"issueKey" validate:"required,max=255"`

	// Title is the issue title.
	Title string `json:"title" validate:"required,max=255"`

	// Description is the issue description.
	Description string `json:"description,omitempty" validate:"omitempty,max=65536"`

	// EpicKey is the issue epic key.
	EpicKey string `json:"epicKey,omitempty" validate:"omitempty,max=255"`

	// Type is the issue type, such as INCIDENT, BUG, REQUIREMENT.
	Type string `json:"type,omitempty" validate:"omitempty,max=50"`

	// Status is the issue status. Must be one of: TODO, DONE, IN_PROGRESS.
	Status string `json:"status" validate:"required,oneof=TODO DONE IN_PROGRESS"`

	// OriginalStatus is the status in your tool, such as: created, open, closed, ...
	OriginalStatus string `json:"originalStatus" validate:"required,max=255"`

	// StoryPoint
	StoryPoint float64 `json:"storyPoint,omitempty" validate:"omitempty"`

	// ResolutionDate is the date when the issue was resolved.
	// Format should be 2020-01-01T12:00:00+00:00.
	ResolutionDate *time.Time `json:"resolutionDate,omitempty" validate:"omitempty"`

	// CreatedDate is the date when the issue was created.
	// Format should be 2020-01-01T12:00:00+00:00.
	CreatedDate *time.Time `json:"createdDate" validate:"required"`

	// UpdatedDate is the date when the issue was last updated.
	// Format should be 2020-01-01T12:00:00+00:00.
	UpdatedDate *time.Time `json:"updatedDate,omitempty" validate:"omitempty"`

	// LeadTimeMinutes measures how long from this issue accepted to develop.
	LeadTimeMinutes uint `json:"leadTimeMinutes,omitempty" validate:"omitempty"`

	// ParentIssueKey is the key of the parent issue.
	ParentIssueKey string `json:"parentIssueKey,omitempty" validate:"omitempty,max=255"`

	// Priority is the issue priority.
	Priority string `json:"priority,omitempty" validate:"omitempty,max=255"`

	// OriginalEstimateMinutes is the original estimate in minutes.
	OriginalEstimateMinutes int64 `json:"originalEstimateMinutes,omitempty" validate:"omitempty"`

	// TimeSpentMinutes is the time spent on the issue in minutes.
	TimeSpentMinutes int64 `json:"timeSpentMinutes,omitempty" validate:"omitempty"`

	// TimeRemainingMinutes is the remaining time in minutes.
	TimeRemainingMinutes int64 `json:"timeRemainingMinutes,omitempty" validate:"omitempty"`

	// CreatorID is the user id of the issue creator.
	CreatorID string `json:"creatorId,omitempty" validate:"omitempty,max=255"`

	// CreatorName is the username of the creator.
	CreatorName string `json:"creatorName,omitempty" validate:"omitempty,max=255"`

	// AssigneeID is the ID of the assignee.
	AssigneeID string `json:"assigneeId,omitempty" validate:"omitempty,max=255"`

	// AssigneeName is the name of the assignee.
	AssigneeName string `json:"assigneeName,omitempty" validate:"omitempty,max=255"`

	// Severity is the severity of the issue.
	Severity string `json:"severity,omitempty" validate:"omitempty,max=255"`

	// Component is the affected component.
	Component string `json:"component,omitempty" validate:"omitempty,max=255"`
}

IncidentRequest defines the request to register an incident (issue).

type IncidentRequestClose

type IncidentRequestClose struct {
	// ConnectionID is the ID of the DevLake connection where to send the incident request.
	ConnectionID uint64 `json:"-" validate:"required"`

	// IssueKey is the Issue key. It needs to be unique in a connection.
	IssueKey string `json:"-" validate:"required,max=255"`
}

IncidentRequestClose defines the request to close an incident (issue).

type Option

type Option func(c *Client)

Option is the interface that allows to set client options.

func WithHTTPClient

func WithHTTPClient(hc HTTPClient) Option

WithHTTPClient injects a custom HTTP client implementation.

Use this for advanced transports, tracing, or test doubles.

func WithPingTimeout

func WithPingTimeout(timeout time.Duration) Option

WithPingTimeout sets the timeout used by HealthCheck.

func WithPingURL

func WithPingURL(pingURL string) Option

WithPingURL overrides the health-check endpoint URL.

This is useful when DevLake is exposed through custom routing paths.

func WithRetryAttempts

func WithRetryAttempts(attempts uint) Option

WithRetryAttempts sets the maximum retry attempts for write requests.

func WithRetryDelay

func WithRetryDelay(value time.Duration) Option

WithRetryDelay sets the delay applied between retry attempts.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the default HTTP timeout for regular API requests.

It is applied only to the default HTTP client that New creates; it has no effect when a custom client is supplied via WithHTTPClient (that client owns its own timeout).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL