Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions plugins/buildkite/api_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package buildkite

import (
"context"

"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/importer"
"github.com/1Password/shell-plugins/sdk/provision"
"github.com/1Password/shell-plugins/sdk/schema"
"github.com/1Password/shell-plugins/sdk/schema/credname"
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
)

func APIToken() schema.CredentialType {
return schema.CredentialType{
Name: credname.APIToken,
DocsURL: sdk.URL("https://buildkite.com/docs/platform/cli"),
ManagementURL: sdk.URL("https://buildkite.com/user/api-access-tokens"),
Fields: []schema.CredentialField{
{
Name: fieldname.Organization,
MarkdownDescription: "Organization slug for your Buildkite account.",
Secret: false,
Composition: &schema.ValueComposition{
Charset: schema.Charset{
Uppercase: true,
Lowercase: true,
Digits: true,
Symbols: false,
},
},
},
{
Name: fieldname.Token,
MarkdownDescription: "API Token used to authenticate with Buildkite.",
Secret: true,
Composition: &schema.ValueComposition{
Length: 45,
Prefix: "bkua_",
Charset: schema.Charset{
Lowercase: true,
Digits: true,
},
},
},
},
DefaultProvisioner: provision.EnvVars(defaultEnvVarMapping),
Importer: importer.TryAll(
importer.TryEnvVarPair(defaultEnvVarMapping),
TryBuildkiteConfigFile(),
)}
}

var defaultEnvVarMapping = map[string]sdk.FieldName{
"BUILDKITE_ORGANIZATION_SLUG": fieldname.Organization,
"BUILDKITE_API_TOKEN": fieldname.Token,
}

// Check if the platform stores the API Token in a local config file, and if so,
// implement the function below to add support for importing it.
func TryBuildkiteConfigFile() sdk.Importer {
return importer.TryFile("~/.config/bk.yaml", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) {
var config Config
if err := contents.ToYAML(&config); err != nil {
out.AddError(err)
return
}

if len(config.Organizations) == 0 {
return
}

for organizationSlug, organization := range config.Organizations {

if organizationSlug == "" || organization.Token == "" {
return
}

out.AddCandidate(sdk.ImportCandidate{
Fields: map[sdk.FieldName]string{
fieldname.Token: organization.Token,
fieldname.Organization: organizationSlug,
},
NameHint: importer.SanitizeNameHint(organizationSlug),
})
}
})
}

type Config struct {
Organizations map[string]Organization `yaml:"organizations"`
}

type Organization struct {
Token string `yaml:"api_token"`
}
91 changes: 91 additions & 0 deletions plugins/buildkite/api_token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package buildkite

import (
"testing"

"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/plugintest"
"github.com/1Password/shell-plugins/sdk/schema/fieldname"
)

func TestAPITokenProvisioner(t *testing.T) {
plugintest.TestProvisioner(t, APIToken().DefaultProvisioner, map[string]plugintest.ProvisionCase{
"default": {
ItemFields: map[sdk.FieldName]string{
fieldname.Organization: "example",
fieldname.Token: "bkua_abcdefghijklmnopqrstuvwxyz1234567890abcd",
},
ExpectedOutput: sdk.ProvisionOutput{
Environment: map[string]string{
"BUILDKITE_ORGANIZATION_SLUG": "example",
"BUILDKITE_API_TOKEN": "bkua_abcdefghijklmnopqrstuvwxyz1234567890abcd",
},
},
},
})
}

func TestAPITokenImporter(t *testing.T) {
plugintest.TestImporter(t, APIToken().Importer, map[string]plugintest.ImportCase{
"environment": {
Environment: map[string]string{
"BUILDKITE_ORGANIZATION_SLUG": "example",
"BUILDKITE_API_TOKEN": "bkua_abcdefghijklmnopqrstuvwxyz1234567890abcd",
},
ExpectedCandidates: []sdk.ImportCandidate{
{
Fields: map[sdk.FieldName]string{
fieldname.Organization: "example",
fieldname.Token: "bkua_abcdefghijklmnopqrstuvwxyz1234567890abcd",
},
},
},
},
"config file default path": {
Files: map[string]string{
"~/.config/bk.yaml": plugintest.LoadFixture(t, "bk.yaml"),
},
ExpectedCandidates: []sdk.ImportCandidate{
{
Fields: map[sdk.FieldName]string{
fieldname.Organization: "example",
fieldname.Token: "bkua_abcdefghijklmnopqrstuvwxyz1234567890abcd",
},
NameHint: "example",
},
{
Fields: map[sdk.FieldName]string{
fieldname.Organization: "example2",
fieldname.Token: "bkua_abcdefghijklmnopqrstuvwxyz1234567890defg",
},
NameHint: "example2",
},
},
},
})
}

func TestAPIKeyNeedsAuth(t *testing.T) {
plugintest.TestNeedsAuth(t, BuildkiteCLI().NeedsAuth, map[string]plugintest.NeedsAuthCase{
"no for --help": {
Args: []string{"--help"},
ExpectedNeedsAuth: false,
},
"no for --version": {
Args: []string{"--version"},
ExpectedNeedsAuth: false,
},
"no for configure": {
Args: []string{"configure"},
ExpectedNeedsAuth: false,
},
"no for without args": {
Args: []string{},
ExpectedNeedsAuth: false,
},
"yes for all other commands": {
Args: []string{"example"},
ExpectedNeedsAuth: true,
},
})
}
26 changes: 26 additions & 0 deletions plugins/buildkite/bk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package buildkite

import (
"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/needsauth"
"github.com/1Password/shell-plugins/sdk/schema"
"github.com/1Password/shell-plugins/sdk/schema/credname"
)

func BuildkiteCLI() schema.Executable {
return schema.Executable{
Name: "Buildkite CLI",
Runs: []string{"bk"},
DocsURL: sdk.URL("https://buildkite.com/docs/cli"),
NeedsAuth: needsauth.IfAll(
needsauth.NotForHelpOrVersion(),
needsauth.NotWithoutArgs(),
needsauth.NotForExactArgs("configure"),
),
Uses: []schema.CredentialUsage{
{
Name: credname.APIToken,
},
},
}
}
22 changes: 22 additions & 0 deletions plugins/buildkite/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package buildkite

import (
"github.com/1Password/shell-plugins/sdk"
"github.com/1Password/shell-plugins/sdk/schema"
)

func New() schema.Plugin {
return schema.Plugin{
Name: "buildkite",
Platform: schema.PlatformInfo{
Name: "Buildkite",
Homepage: sdk.URL("https://buildkite.com"),
},
Credentials: []schema.CredentialType{
APIToken(),
},
Executables: []schema.Executable{
BuildkiteCLI(),
},
}
}
5 changes: 5 additions & 0 deletions plugins/buildkite/test-fixtures/bk.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
organizations:
example:
api_token: bkua_abcdefghijklmnopqrstuvwxyz1234567890abcd
example2:
api_token: bkua_abcdefghijklmnopqrstuvwxyz1234567890defg