fluxcd / go-git-providers

Git provider client for Go
https://fluxcd.io
Apache License 2.0
71 stars 33 forks source link

go-git-providers

godev build Go Report Card LICENSE Release

go-git-providers is a general-purpose Go client for interacting with Git providers' APIs.

Supported providers:

Features

Operations and Design

The top-level gitprovider.Client has the following sub-clients with their described capabilities:

The sub-clients above return gitprovider.Organization or gitprovider.{Org,User}Repository interfaces. These object interfaces lets you access their data (through their .Get() function), internal, provider-specific representation (through their .APIObject() function), or sub-resources like deploy keys and teams.

The following object-scoped clients are available:

Wait, how do I Delete or Update an object?

That's done on the returned objects themselves, using the following Updatable, Reconcilable and Deletable interfaces implemented by {Org,User}Repository, DeployKey and TeamAccess:

// Updatable is an interface which all objects that can be updated
// using the Client implement.
type Updatable interface {
    // Update will apply the desired state in this object to the server.
    // Only set fields will be respected (i.e. PATCH behaviour).
    // In order to apply changes to this object, use the .Set({Resource}Info) error
    // function, or cast .APIObject() to a pointer to the provider-specific type
    // and set custom fields there.
    //
    // ErrNotFound is returned if the resource does not exist.
    //
    // The internal API object will be overridden with the received server data.
    Update(ctx context.Context) error
}

// Deletable is an interface which all objects that can be deleted
// using the Client implement.
type Deletable interface {
    // Delete deletes the current resource irreversibly.
    //
    // ErrNotFound is returned if the resource doesn't exist anymore.
    Delete(ctx context.Context) error
}

// Reconcilable is an interface which all objects that can be reconciled
// using the Client implement.
type Reconcilable interface {
    // Reconcile makes sure the desired state in this object (called "req" here) becomes
    // the actual state in the backing Git provider.
    //
    // If req doesn't exist under the hood, it is created (actionTaken == true).
    // If req doesn't equal the actual state, the resource will be updated (actionTaken == true).
    // If req is already the actual state, this is a no-op (actionTaken == false).
    //
    // The internal API object will be overridden with the received server data if actionTaken == true.
    Reconcile(ctx context.Context) (actionTaken bool, err error)
}

In order to access the provider-specific, internal object, all resources implement the gitprovider.Object interface:

// Object is the interface all types should implement.
type Object interface {
    // APIObject returns the underlying value that was returned from the server.
    // This is always a pointer to a struct.
    APIObject() interface{}
}

So, how do I set the desired state for an object before running Update or Reconcile?

Using the Get() {Resource}Info or Set({Resource}Info) error methods. An example as follows, for TeamAccess:

// TeamAccess describes a binding between a repository and a team.
type TeamAccess interface {
    // TeamAccess implements the Object interface,
    // allowing access to the underlying object returned from the API.
    Object
    // The deploy key can be updated.
    Updatable
    // The deploy key can be reconciled.
    Reconcilable
    // The deploy key can be deleted.
    Deletable
    // RepositoryBound returns repository reference details.
    RepositoryBound

    // Get returns high-level information about this team access for the repository.
    Get() TeamAccessInfo
    // Set sets high-level desired state for this team access object. In order to apply these changes in
    // the Git provider, run .Update() or .Reconcile().
    Set(TeamAccessInfo) error
}

// TeamAccessInfo contains high-level information about a team's access to a repository.
type TeamAccessInfo struct {
    // Name describes the name of the team. The team name may contain slashes.
    // +required
    Name string `json:"name"`

    // Permission describes the permission level for which the team is allowed to operate.
    // Default: pull.
    // Available options: See the RepositoryPermission enum.
    // +optional
    Permission *RepositoryPermission `json:"permission,omitempty"`
}

Examples

See the following (automatically tested) examples:

Getting Help

If you have any questions about this library:

Your feedback is always welcome!

License

Apache 2.0