From d6b64a4dc9b0d5c592342f4136bbb77bd2546698 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 17:03:08 -0700 Subject: [PATCH 01/29] feat(cli): adds docs releaser type --- .github/workflows/ci.yml | 18 +- blueprint.cue | 3 + cli/go.mod | 7 +- cli/go.sum | 10 + cli/pkg/providers/aws/mocks/s3.go | 196 +++++++++++++++++++ cli/pkg/providers/aws/s3.go | 154 +++++++++++++++ cli/pkg/release/providers/docs.go | 161 +++++++++++++++ cli/pkg/release/releaser.go | 4 + docs/blueprint.cue | 16 +- lib/schema/blueprint/global/ci.cue | 6 +- lib/schema/blueprint/global/cue_types_gen.go | 18 ++ lib/schema/blueprint/global/release.cue | 16 ++ 12 files changed, 596 insertions(+), 13 deletions(-) create mode 100644 cli/pkg/providers/aws/mocks/s3.go create mode 100644 cli/pkg/providers/aws/s3.go create mode 100644 cli/pkg/release/providers/docs.go create mode 100644 lib/schema/blueprint/global/release.cue diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edcdd36c..7b24ce3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,15 +135,15 @@ jobs: secrets: earthly_token: ${{ secrets.earthly_token }} - docs: - uses: input-output-hk/catalyst-forge/.github/workflows/docs.yml@master - needs: [discover, check, build, test] - if: (fromJson(needs.discover.outputs.earthfiles)['^docs(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^docs(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # docs: + # uses: input-output-hk/catalyst-forge/.github/workflows/docs.yml@ci/v1.8.1 + # needs: [discover, check, build, test] + # if: (fromJson(needs.discover.outputs.earthfiles)['^docs(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^docs(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} release: uses: input-output-hk/catalyst-forge/.github/workflows/release.yml@master diff --git a/blueprint.cue b/blueprint.cue index 7455ad63..a2a51a11 100644 --- a/blueprint.cue +++ b/blueprint.cue @@ -10,6 +10,9 @@ global: { registries: [ "ghcr.io/input-output-hk/catalyst-forge", ] + release: docs: { + bucket: "docs.dev.projectcatalyst.io" + } providers: { aws: { ecr: { diff --git a/cli/go.mod b/cli/go.mod index bb4bcf55..2a87f2e9 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -9,6 +9,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.32.6 github.com/aws/aws-sdk-go-v2/config v1.27.40 github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 + github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.1.1 github.com/charmbracelet/lipgloss v0.13.0 @@ -23,6 +24,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/willabides/kongplete v0.4.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c + gopkg.in/yaml.v3 v3.0.1 kcl-lang.io/kpm v0.11.0 ) @@ -46,13 +48,17 @@ require ( github.com/adrg/xdg v0.5.3 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230219212500-1f9a474cc2dc // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.38 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 // indirect github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 // indirect @@ -242,7 +248,6 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect helm.sh/helm/v3 v3.17.0 // indirect k8s.io/api v0.32.2 // indirect k8s.io/apiextensions-apiserver v0.32.2 // indirect diff --git a/cli/go.sum b/cli/go.sum index dcfef905..4339c60f 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -243,6 +243,8 @@ github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw= github.com/aws/aws-sdk-go-v2/config v1.27.40 h1:sie4mPBGFOO+Z27+yHzvyN31G20h/bf2xb5mCbpLv2Q= github.com/aws/aws-sdk-go-v2/config v1.27.40/go.mod h1:4KW7Aa5tNo+0VHnuLnnE1vPHtwMurlNZNS65IdcewHA= github.com/aws/aws-sdk-go-v2/credentials v1.17.38 h1:iM90eRhCeZtlkzCNCG1JysOzJXGYf5rx80aD1lUgNDU= @@ -255,12 +257,20 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 h1:mimdLQkIX1zr8GIPY1ZtALdBQGxcASiBd2MOp8m/dMc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16/go.mod h1:YHk6owoSwrIsok+cAH9PENCOGoH5PU2EllX4vLtSrsY= github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 h1:R+5XKIJga2K9Dkj0/iQ6fD/MBGo02oxGGFTc512lK/Q= github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7/go.mod h1:fDPQV/6ONOQOjvtKhtypIy1wcGLcKYtoK/lvZ9fyDGQ= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 h1:GckUnpm4EJOAio1c8o25a+b3lVfwVzC9gnSBqiiNmZM= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18/go.mod h1:Br6+bxfG33Dk3ynmkhsW2Z/t9D4+lRqdLDNCKi85w0U= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY= +github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 h1:mx2ucgtv+MWzJesJY9Ig/8AFHgoE5FwLXwUVgW/FGdI= +github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 h1:EoPbZg+DGTRqKKhwk5uDviV9yvx65r1kyoNNC02ZH4Y= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4/go.mod h1:WyLS5qwXHtjKAONYZq/4ewdd+hcVsa3LBu77Ow5uj3k= github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 h1:ck/Y8XWNR1gHa4BFkwE3oSu7XDJGwl+8TI7E/RB2EcQ= diff --git a/cli/pkg/providers/aws/mocks/s3.go b/cli/pkg/providers/aws/mocks/s3.go new file mode 100644 index 00000000..77226126 --- /dev/null +++ b/cli/pkg/providers/aws/mocks/s3.go @@ -0,0 +1,196 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package mocks + +import ( + "context" + "github.com/aws/aws-sdk-go-v2/service/s3" + "sync" +) + +// AWSS3ClientMock is a mock implementation of aws.AWSS3Client. +// +// func TestSomethingThatUsesAWSS3Client(t *testing.T) { +// +// // make and configure a mocked aws.AWSS3Client +// mockedAWSS3Client := &AWSS3ClientMock{ +// DeleteObjectFunc: func(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) { +// panic("mock out the DeleteObject method") +// }, +// ListObjectsV2Func: func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) { +// panic("mock out the ListObjectsV2 method") +// }, +// PutObjectFunc: func(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) { +// panic("mock out the PutObject method") +// }, +// } +// +// // use mockedAWSS3Client in code that requires aws.AWSS3Client +// // and then make assertions. +// +// } +type AWSS3ClientMock struct { + // DeleteObjectFunc mocks the DeleteObject method. + DeleteObjectFunc func(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) + + // ListObjectsV2Func mocks the ListObjectsV2 method. + ListObjectsV2Func func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) + + // PutObjectFunc mocks the PutObject method. + PutObjectFunc func(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) + + // calls tracks calls to the methods. + calls struct { + // DeleteObject holds details about calls to the DeleteObject method. + DeleteObject []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Params is the params argument value. + Params *s3.DeleteObjectInput + // OptFns is the optFns argument value. + OptFns []func(*s3.Options) + } + // ListObjectsV2 holds details about calls to the ListObjectsV2 method. + ListObjectsV2 []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Params is the params argument value. + Params *s3.ListObjectsV2Input + // OptFns is the optFns argument value. + OptFns []func(*s3.Options) + } + // PutObject holds details about calls to the PutObject method. + PutObject []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Params is the params argument value. + Params *s3.PutObjectInput + // OptFns is the optFns argument value. + OptFns []func(*s3.Options) + } + } + lockDeleteObject sync.RWMutex + lockListObjectsV2 sync.RWMutex + lockPutObject sync.RWMutex +} + +// DeleteObject calls DeleteObjectFunc. +func (mock *AWSS3ClientMock) DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) { + if mock.DeleteObjectFunc == nil { + panic("AWSS3ClientMock.DeleteObjectFunc: method is nil but AWSS3Client.DeleteObject was just called") + } + callInfo := struct { + Ctx context.Context + Params *s3.DeleteObjectInput + OptFns []func(*s3.Options) + }{ + Ctx: ctx, + Params: params, + OptFns: optFns, + } + mock.lockDeleteObject.Lock() + mock.calls.DeleteObject = append(mock.calls.DeleteObject, callInfo) + mock.lockDeleteObject.Unlock() + return mock.DeleteObjectFunc(ctx, params, optFns...) +} + +// DeleteObjectCalls gets all the calls that were made to DeleteObject. +// Check the length with: +// +// len(mockedAWSS3Client.DeleteObjectCalls()) +func (mock *AWSS3ClientMock) DeleteObjectCalls() []struct { + Ctx context.Context + Params *s3.DeleteObjectInput + OptFns []func(*s3.Options) +} { + var calls []struct { + Ctx context.Context + Params *s3.DeleteObjectInput + OptFns []func(*s3.Options) + } + mock.lockDeleteObject.RLock() + calls = mock.calls.DeleteObject + mock.lockDeleteObject.RUnlock() + return calls +} + +// ListObjectsV2 calls ListObjectsV2Func. +func (mock *AWSS3ClientMock) ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) { + if mock.ListObjectsV2Func == nil { + panic("AWSS3ClientMock.ListObjectsV2Func: method is nil but AWSS3Client.ListObjectsV2 was just called") + } + callInfo := struct { + Ctx context.Context + Params *s3.ListObjectsV2Input + OptFns []func(*s3.Options) + }{ + Ctx: ctx, + Params: params, + OptFns: optFns, + } + mock.lockListObjectsV2.Lock() + mock.calls.ListObjectsV2 = append(mock.calls.ListObjectsV2, callInfo) + mock.lockListObjectsV2.Unlock() + return mock.ListObjectsV2Func(ctx, params, optFns...) +} + +// ListObjectsV2Calls gets all the calls that were made to ListObjectsV2. +// Check the length with: +// +// len(mockedAWSS3Client.ListObjectsV2Calls()) +func (mock *AWSS3ClientMock) ListObjectsV2Calls() []struct { + Ctx context.Context + Params *s3.ListObjectsV2Input + OptFns []func(*s3.Options) +} { + var calls []struct { + Ctx context.Context + Params *s3.ListObjectsV2Input + OptFns []func(*s3.Options) + } + mock.lockListObjectsV2.RLock() + calls = mock.calls.ListObjectsV2 + mock.lockListObjectsV2.RUnlock() + return calls +} + +// PutObject calls PutObjectFunc. +func (mock *AWSS3ClientMock) PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) { + if mock.PutObjectFunc == nil { + panic("AWSS3ClientMock.PutObjectFunc: method is nil but AWSS3Client.PutObject was just called") + } + callInfo := struct { + Ctx context.Context + Params *s3.PutObjectInput + OptFns []func(*s3.Options) + }{ + Ctx: ctx, + Params: params, + OptFns: optFns, + } + mock.lockPutObject.Lock() + mock.calls.PutObject = append(mock.calls.PutObject, callInfo) + mock.lockPutObject.Unlock() + return mock.PutObjectFunc(ctx, params, optFns...) +} + +// PutObjectCalls gets all the calls that were made to PutObject. +// Check the length with: +// +// len(mockedAWSS3Client.PutObjectCalls()) +func (mock *AWSS3ClientMock) PutObjectCalls() []struct { + Ctx context.Context + Params *s3.PutObjectInput + OptFns []func(*s3.Options) +} { + var calls []struct { + Ctx context.Context + Params *s3.PutObjectInput + OptFns []func(*s3.Options) + } + mock.lockPutObject.RLock() + calls = mock.calls.PutObject + mock.lockPutObject.RUnlock() + return calls +} diff --git a/cli/pkg/providers/aws/s3.go b/cli/pkg/providers/aws/s3.go new file mode 100644 index 00000000..3dd1bdea --- /dev/null +++ b/cli/pkg/providers/aws/s3.go @@ -0,0 +1,154 @@ +package aws + +import ( + "context" + "fmt" + "io" + "log/slog" + "mime" + "path/filepath" + + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go/aws" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs" + "github.com/input-output-hk/catalyst-forge/lib/tools/walker" +) + +//go:generate go run github.com/matryer/moq@latest -skip-ensure --pkg mocks -out mocks/s3.go . AWSS3Client + +// AWSS3Client is an interface for an AWS S3 client. +type AWSS3Client interface { + PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) + DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) + ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) +} + +// S3Client is a client for interacting with AWS S3. +type S3Client struct { + client AWSS3Client + logger *slog.Logger + walker walker.Walker +} + +// UploadFile uploads a file to S3. +func (c *S3Client) UploadFile(bucket, key string, body io.Reader, contentType string) error { + input := &s3.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + Body: body, + ContentType: aws.String(contentType), + } + + _, err := c.client.PutObject(context.Background(), input) + if err != nil { + return fmt.Errorf("failed to upload file to S3: %w", err) + } + + c.logger.Debug("Successfully uploaded file to S3", "bucket", bucket, "key", key) + return nil +} + +// DeleteFile deletes a file from S3. +func (c *S3Client) DeleteFile(bucket, key string) error { + input := &s3.DeleteObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + } + + _, err := c.client.DeleteObject(context.Background(), input) + if err != nil { + return fmt.Errorf("failed to delete file from S3: %w", err) + } + + c.logger.Debug("Successfully deleted file from S3", "bucket", bucket, "key", key) + return nil +} + +// DeleteDirectory deletes all objects in a directory (prefix) from S3. +func (c *S3Client) DeleteDirectory(bucket, prefix string) error { + listInput := &s3.ListObjectsV2Input{ + Bucket: aws.String(bucket), + Prefix: aws.String(prefix), + } + + listOutput, err := c.client.ListObjectsV2(context.Background(), listInput) + if err != nil { + return fmt.Errorf("failed to list objects in S3: %w", err) + } + + for _, object := range listOutput.Contents { + if err := c.DeleteFile(bucket, *object.Key); err != nil { + return fmt.Errorf("failed to delete object %s: %w", *object.Key, err) + } + } + + c.logger.Debug("Successfully deleted directory from S3", "bucket", bucket, "prefix", prefix) + return nil +} + +// UploadDirectory uploads all files from a local directory to S3. +func (c *S3Client) UploadDirectory(bucket, prefix string, localPath string, fs fs.Filesystem) error { + if c.walker == nil { + return fmt.Errorf("walker not initialized") + } + + c.logger.Info("Uploading directory to S3", "bucket", bucket, "prefix", prefix, "localPath", localPath) + + return c.walker.Walk(localPath, func(path string, fileType walker.FileType, getReader func() (walker.FileSeeker, error)) error { + if fileType != walker.FileTypeFile { + return nil + } + + relPath, err := filepath.Rel(localPath, path) + if err != nil { + return fmt.Errorf("failed to calculate relative path: %w", err) + } + + s3Key := filepath.Join(prefix, relPath) + s3Key = filepath.ToSlash(s3Key) + + reader, err := getReader() + if err != nil { + return fmt.Errorf("failed to get file reader for %s: %w", path, err) + } + defer reader.Close() + + contentType := mime.TypeByExtension(filepath.Ext(path)) + if contentType == "" { + contentType = "application/octet-stream" + } + + c.logger.Debug("Uploading file", "localPath", path, "s3Key", s3Key, "contentType", contentType) + if err := c.UploadFile(bucket, s3Key, reader, contentType); err != nil { + return fmt.Errorf("failed to upload file %s: %w", path, err) + } + + return nil + }) +} + +// NewS3Client returns a new S3 client. +func NewS3Client(logger *slog.Logger) (S3Client, error) { + cfg, err := NewConfig() + if err != nil { + return S3Client{}, err + } + + c := s3.NewFromConfig(cfg) + w := walker.NewDefaultFSWalker(logger) + + return S3Client{ + client: c, + logger: logger, + walker: &w, + }, nil +} + +// NewCustomS3Client returns a new custom S3 client. +func NewCustomS3Client(client AWSS3Client, walker walker.Walker, logger *slog.Logger) S3Client { + return S3Client{ + client: client, + logger: logger, + walker: walker, + } +} diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go new file mode 100644 index 00000000..e401b025 --- /dev/null +++ b/cli/pkg/release/providers/docs.go @@ -0,0 +1,161 @@ +package providers + +import ( + "fmt" + "log/slog" + "path/filepath" + + "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" + "github.com/input-output-hk/catalyst-forge/cli/pkg/events" + "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" + "github.com/input-output-hk/catalyst-forge/cli/pkg/run" + "github.com/input-output-hk/catalyst-forge/lib/project/project" + sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" +) + +// DocsReleaserConfig is the configuration for the docs release. +type DocsReleaserConfig struct { + Name string `json:"name"` +} + +// DocsReleaser is a provider that releases the docs for a project. +type DocsReleaser struct { + config DocsReleaserConfig + force bool + fs fs.Filesystem + handler events.EventHandler + logger *slog.Logger + project project.Project + release sp.Release + releaseName string + runner earthly.ProjectRunner + s3 aws.S3Client + workdir string +} + +// Release runs the docs release. +func (r *DocsReleaser) Release() error { + r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) + if err := r.run(r.workdir); err != nil { + return fmt.Errorf("failed to run docs release target: %w", err) + } + + if err := r.validateArtifacts(r.workdir); err != nil { + return fmt.Errorf("failed to validate artifacts: %w", err) + } + + if !r.handler.Firing(&r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { + r.logger.Info("No release event is firing, skipping release") + return nil + } + + if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { + return fmt.Errorf("global docs release configuration not found") + } + + docsConfig := r.project.Blueprint.Global.Ci.Release.Docs + if docsConfig.Bucket == "" { + return fmt.Errorf("no S3 bucket specified in global docs configuration") + } + + projectName := r.config.Name + if projectName == "" { + projectName = r.project.Name + } + + s3Path := projectName + if docsConfig.Path != "" { + s3Path = docsConfig.Path + "/" + projectName + } + + r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) + if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { + return fmt.Errorf("failed to clean existing docs from S3: %w", err) + } + + finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) + r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) + if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { + return fmt.Errorf("failed to upload docs to S3: %w", err) + } + + r.logger.Info("Docs release complete") + return nil +} + +// run runs the docs release target. +func (r *DocsReleaser) run(path string) error { + return r.runner.RunTarget( + r.release.Target, + earthly.WithArtifact(path), + ) +} + +// validateArtifacts validates that the expected artifacts exist. +func (r *DocsReleaser) validateArtifacts(path string) error { + r.logger.Info("Validating docs artifacts", "path", path) + exists, err := r.fs.Exists(path) + if err != nil { + return fmt.Errorf("failed to check if output folder exists: %w", err) + } else if !exists { + return fmt.Errorf("unable to find output folder: %s", path) + } + + children, err := r.fs.ReadDir(path) + if err != nil { + return fmt.Errorf("failed to read output folder: %w", err) + } + + if len(children) == 0 { + return fmt.Errorf("no docs artifacts found") + } + + return nil +} + +// NewDocsReleaser creates a new docs release provider. +func NewDocsReleaser( + ctx run.RunContext, + project project.Project, + name string, + force bool, +) (*DocsReleaser, error) { + release, ok := project.Blueprint.Project.Release[name] + if !ok { + return nil, fmt.Errorf("unknown release: %s", name) + } + + var config DocsReleaserConfig + if err := parseConfig(&project, name, &config); err != nil { + return nil, fmt.Errorf("failed to parse release config: %w", err) + } + + fs := billy.NewBaseOsFS() + workdir, err := fs.TempDir("", "catalyst-forge-docs-") + if err != nil { + return nil, fmt.Errorf("failed to create temporary directory: %w", err) + } + + s3, err := aws.NewS3Client(ctx.Logger) + if err != nil { + return nil, fmt.Errorf("failed to create S3 client: %w", err) + } + + handler := events.NewDefaultEventHandler(ctx.Logger) + runner := earthly.NewDefaultProjectRunner(ctx, &project) + return &DocsReleaser{ + config: config, + force: force, + fs: fs, + handler: &handler, + logger: ctx.Logger, + project: project, + release: release, + releaseName: name, + runner: &runner, + s3: s3, + workdir: workdir, + }, nil +} diff --git a/cli/pkg/release/releaser.go b/cli/pkg/release/releaser.go index 7022db29..cf246a2a 100644 --- a/cli/pkg/release/releaser.go +++ b/cli/pkg/release/releaser.go @@ -13,6 +13,7 @@ type ReleaserType string const ( ReleaserTypeCue ReleaserType = "cue" ReleaserTypeDocker ReleaserType = "docker" + ReleaserTypeDocs ReleaserType = "docs" ReleaserTypeGithub ReleaserType = "github" ReleaserTypeKCL ReleaserType = "kcl" ReleaserTypeTimoni ReleaserType = "timoni" @@ -52,6 +53,9 @@ func NewDefaultReleaserStore() *ReleaserStore { ReleaserTypeDocker: func(ctx run.RunContext, project project.Project, name string, force bool) (Releaser, error) { return providers.NewDockerReleaser(ctx, project, name, force) }, + ReleaserTypeDocs: func(ctx run.RunContext, project project.Project, name string, force bool) (Releaser, error) { + return providers.NewDocsReleaser(ctx, project, name, force) + }, ReleaserTypeGithub: func(ctx run.RunContext, project project.Project, name string, force bool) (Releaser, error) { return providers.NewGithubReleaser(ctx, project, name, force) }, diff --git a/docs/blueprint.cue b/docs/blueprint.cue index dd85bd5c..30d7421b 100644 --- a/docs/blueprint.cue +++ b/docs/blueprint.cue @@ -1 +1,15 @@ -project: name: "forge-docs" +project: { + name: "forge-docs" + + release: { + docs: { + on: { + always: {} + } + + config: { + name: "forge" + } + } + } +} diff --git a/lib/schema/blueprint/global/ci.cue b/lib/schema/blueprint/global/ci.cue index b8c9b38e..00d2b758 100644 --- a/lib/schema/blueprint/global/ci.cue +++ b/lib/schema/blueprint/global/ci.cue @@ -16,7 +16,9 @@ import ( // Registries contains the container registries to push images to. registries?: [...string] + // Release contains the configuration for the release of a project. + release?: #Release + // Secrets contains global secrets that will be passed to all targets. - secrets?:[...common.#Secret] + secrets?: [...common.#Secret] } - diff --git a/lib/schema/blueprint/global/cue_types_gen.go b/lib/schema/blueprint/global/cue_types_gen.go index 8387f3be..32ec7c71 100644 --- a/lib/schema/blueprint/global/cue_types_gen.go +++ b/lib/schema/blueprint/global/cue_types_gen.go @@ -18,6 +18,9 @@ type CI struct { // Registries contains the container registries to push images to. Registries []string `json:"registries,omitempty"` + // Release contains the configuration for the release of a project. + Release *Release `json:"release,omitempty"` + // Secrets contains global secrets that will be passed to all targets. Secrets []common.Secret `json:"secrets,omitempty"` } @@ -71,6 +74,21 @@ type Global struct { State any/* CUE top */ `json:"state,omitempty"` } +// Release contains the configuration for the release of a project. +type Release struct { + // Docs is the configuration for the docs release type. + Docs *DocsRelease `json:"docs,omitempty"` +} + +// DocsRelease contains the configuration for the docs release type. +type DocsRelease struct { + // Bucket is the name of the S3 bucket to upload the docs to. + Bucket string `json:"bucket"` + + // Path is the subpath within the bucket to upload the docs to. + Path string `json:"path,omitempty"` +} + type Repo struct { // Name contains the name of the repository (e.g. "owner/repo-name"). Name string `json:"name"` diff --git a/lib/schema/blueprint/global/release.cue b/lib/schema/blueprint/global/release.cue new file mode 100644 index 00000000..4e791fd3 --- /dev/null +++ b/lib/schema/blueprint/global/release.cue @@ -0,0 +1,16 @@ +package global + +// Release contains the configuration for the release of a project. +#Release: { + // Docs is the configuration for the docs release type. + docs?: #DocsRelease +} + +// DocsRelease contains the configuration for the docs release type. +#DocsRelease: { + // Bucket is the name of the S3 bucket to upload the docs to. + bucket: string + + // Path is the subpath within the bucket to upload the docs to. + path?: string | *"" +} From 27d617a5bfc72a77345435ff4d3c8ea859600963 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 17:53:20 -0700 Subject: [PATCH 02/29] wip: testing --- .github/workflows/test.yml | 32 ++++++++++++++ cli/pkg/release/providers/docs.go | 73 +++++++++++++++++++++++-------- lib/tools/git/github/env.go | 45 +++++++++++++++++++ 3 files changed, 131 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..f78c5456 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,32 @@ +name: Test + +on: + push: + +permissions: + id-token: write + contents: write + packages: write + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Local Forge + id: install-local + uses: input-output-hk/catalyst-forge/actions/install-local@master + - name: Check forge version + id: local + run: | + forge version + - name: Setup CI + uses: input-output-hk/catalyst-forge/actions/setup@master + with: + skip_docker: 'true' + skip_github: 'true' + skip_earthly_install: ${{ steps.install-local.outputs.cache-hit == false }} + skip_earthly_satellite: ${{ steps.install-local.outputs.cache-hit == false }} + - name: Test + run: | + forge release -vvv ./docs docs \ No newline at end of file diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index e401b025..e958087a 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -3,7 +3,6 @@ package providers import ( "fmt" "log/slog" - "path/filepath" "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" "github.com/input-output-hk/catalyst-forge/cli/pkg/events" @@ -13,6 +12,8 @@ import ( sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" + "github.com/input-output-hk/catalyst-forge/lib/tools/git" + "github.com/input-output-hk/catalyst-forge/lib/tools/git/github" ) // DocsReleaserConfig is the configuration for the docs release. @@ -27,7 +28,7 @@ type DocsReleaser struct { fs fs.Filesystem handler events.EventHandler logger *slog.Logger - project project.Project + project *project.Project release sp.Release releaseName string runner earthly.ProjectRunner @@ -46,43 +47,77 @@ func (r *DocsReleaser) Release() error { return fmt.Errorf("failed to validate artifacts: %w", err) } - if !r.handler.Firing(&r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { + if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { r.logger.Info("No release event is firing, skipping release") return nil } - if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { - return fmt.Errorf("global docs release configuration not found") - } + env := github.NewGithubEnv(r.logger) + if env.IsPR() { + pr := env.GetPRNumber() + if pr == 0 { + return fmt.Errorf("failed to get PR number") + } - docsConfig := r.project.Blueprint.Global.Ci.Release.Docs - if docsConfig.Bucket == "" { - return fmt.Errorf("no S3 bucket specified in global docs configuration") + r.logger.Info("PR number", "pr", pr) } + // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { + // return fmt.Errorf("global docs release configuration not found") + // } + + // docsConfig := r.project.Blueprint.Global.Ci.Release.Docs + // if docsConfig.Bucket == "" { + // return fmt.Errorf("no S3 bucket specified in global docs configuration") + // } + + // s3Path, err := r.generatePath() + // if err != nil { + // return fmt.Errorf("failed to generate S3 path: %w", err) + // } + + // r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) + // if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { + // return fmt.Errorf("failed to clean existing docs from S3: %w", err) + // } + + // finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) + // r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) + // if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { + // return fmt.Errorf("failed to upload docs to S3: %w", err) + // } + + r.logger.Info("Docs release complete") + return nil +} + +// generatePath generates the S3 path for the docs. +func (r *DocsReleaser) generatePath() (string, error) { projectName := r.config.Name if projectName == "" { projectName = r.project.Name } + docsConfig := r.project.Blueprint.Global.Ci.Release.Docs + if docsConfig.Bucket == "" { + return "", fmt.Errorf("no S3 bucket specified in global docs configuration") + } + s3Path := projectName if docsConfig.Path != "" { s3Path = docsConfig.Path + "/" + projectName } - r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) - if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { - return fmt.Errorf("failed to clean existing docs from S3: %w", err) + branch, err := git.GetBranch(r.project.Repo) + if err != nil { + return "", fmt.Errorf("failed to get branch: %w", err) } - finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) - r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) - if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { - return fmt.Errorf("failed to upload docs to S3: %w", err) + if branch == r.project.Blueprint.Global.Repo.DefaultBranch { + return s3Path, nil } - r.logger.Info("Docs release complete") - return nil + return s3Path + "/" + branch, nil } // run runs the docs release target. @@ -151,7 +186,7 @@ func NewDocsReleaser( fs: fs, handler: &handler, logger: ctx.Logger, - project: project, + project: &project, release: release, releaseName: name, runner: &runner, diff --git a/lib/tools/git/github/env.go b/lib/tools/git/github/env.go index debfb479..b2854a02 100644 --- a/lib/tools/git/github/env.go +++ b/lib/tools/git/github/env.go @@ -5,6 +5,7 @@ import ( "io" "log/slog" "os" + "strconv" "strings" "github.com/google/go-github/v66/github" @@ -23,6 +24,7 @@ type GithubEnv struct { logger *slog.Logger } +// GetBranch returns the current branch from the CI environment. func (g *GithubEnv) GetBranch() string { ref, ok := os.LookupEnv("GITHUB_HEAD_REF") if !ok || ref == "" { @@ -73,6 +75,49 @@ func (g *GithubEnv) GetTag() string { return "" } +// IsPR returns whether the current environment is associated with a pull request. +func (g *GithubEnv) IsPR() bool { + if _, ok := os.LookupEnv("GITHUB_HEAD_REF"); ok { + return true + } + + if g.GetEventType() == "pull_request" { + return true + } + + return false +} + +// GetPRNumber returns the pull request number if the current environment is associated with a PR. +// Returns 0 if not in a PR context or if the PR number cannot be determined. +func (g *GithubEnv) GetPRNumber() int { + if !g.IsPR() { + return 0 + } + + if prNumberStr, ok := os.LookupEnv("GITHUB_EVENT_NUMBER"); ok { + if prNumber, err := strconv.Atoi(prNumberStr); err == nil { + return prNumber + } + } + + if g.HasEvent() { + event, err := g.GetEventPayload() + if err != nil { + g.logger.Debug("Failed to get event payload for PR number", "error", err) + return 0 + } + + if prEvent, ok := event.(*github.PullRequestEvent); ok { + if prEvent.PullRequest != nil && prEvent.PullRequest.Number != nil { + return *prEvent.PullRequest.Number + } + } + } + + return 0 +} + // HasEvent returns whether a GitHub event payload exists. func (g *GithubEnv) HasEvent() bool { _, pathExists := os.LookupEnv("GITHUB_EVENT_PATH") From f1dd29026f1141a876daf995cbcabd2e34e77af8 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 17:56:13 -0700 Subject: [PATCH 03/29] wip: testing --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f78c5456..91ac6b0c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,9 @@ name: Test on: push: + branches: [master] + tags: ['**'] + pull_request: permissions: id-token: write From dfab2b37e771c1e86395f8dfbe2d6e36316ff3f5 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:03:16 -0700 Subject: [PATCH 04/29] wip: testing --- cli/pkg/release/providers/docs.go | 10 +++- lib/tools/git/github/pr.go | 81 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 lib/tools/git/github/pr.go diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index e958087a..23e37af2 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -3,6 +3,7 @@ package providers import ( "fmt" "log/slog" + "strings" "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" "github.com/input-output-hk/catalyst-forge/cli/pkg/events" @@ -59,7 +60,14 @@ func (r *DocsReleaser) Release() error { return fmt.Errorf("failed to get PR number") } - r.logger.Info("PR number", "pr", pr) + prClient, err := github.NewPRClient(r.logger) + if err != nil { + return fmt.Errorf("failed to create PR client: %w", err) + } + + owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] + repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] + prClient.PostComment(owner, repo, pr, "Hello, world!") } // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { diff --git a/lib/tools/git/github/pr.go b/lib/tools/git/github/pr.go new file mode 100644 index 00000000..f141cf6a --- /dev/null +++ b/lib/tools/git/github/pr.go @@ -0,0 +1,81 @@ +package github + +import ( + "context" + "fmt" + "log/slog" + "os" + + "github.com/google/go-github/v66/github" +) + +var ( + ErrNoGitHubToken = fmt.Errorf("no GitHub token found") + ErrNoRepository = fmt.Errorf("no repository information found") + ErrInvalidPR = fmt.Errorf("invalid pull request number") +) + +// PRClient provides functionality for interacting with pull requests. +type PRClient struct { + client *github.Client + logger *slog.Logger +} + +// CommentOptions contains options for posting a comment. +type CommentOptions struct { + // Body is the comment content + Body string + // CommitID is the specific commit to comment on (optional) + CommitID string + // Path is the file path to comment on (optional) + Path string + // Position is the line position in the file (optional) + Position int +} + +// PostComment posts a comment to a pull request. +func (p *PRClient) PostComment(owner, repo string, prNumber int, body string) error { + if prNumber <= 0 { + return ErrInvalidPR + } + + if body == "" { + return fmt.Errorf("comment body cannot be empty") + } + + comment := &github.IssueComment{ + Body: &body, + } + + p.logger.Debug("Posting comment to PR", "owner", owner, "repo", repo, "pr", prNumber) + _, _, err := p.client.Issues.CreateComment(context.Background(), owner, repo, prNumber, comment) + if err != nil { + return fmt.Errorf("failed to post comment: %w", err) + } + + p.logger.Info("Successfully posted comment to PR", "owner", owner, "repo", repo, "pr", prNumber) + return nil +} + +// NewPRClient creates a new PRClient with authentication from environment. +func NewPRClient(logger *slog.Logger) (*PRClient, error) { + token := os.Getenv("GITHUB_TOKEN") + if token == "" { + return nil, ErrNoGitHubToken + } + + client := github.NewClient(nil).WithAuthToken(token) + + return &PRClient{ + client: client, + logger: logger, + }, nil +} + +// NewCustomPRClient creates a new PRClient with a custom GitHub client. +func NewCustomPRClient(client *github.Client, logger *slog.Logger) *PRClient { + return &PRClient{ + client: client, + logger: logger, + } +} From 91a5208ebb46fa92597fbe771d17fdb0954130ff Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:15:58 -0700 Subject: [PATCH 05/29] wip: testing --- .github/workflows/test.yml | 4 +++- cli/pkg/release/providers/docs.go | 11 ++++++++--- lib/tools/git/github/pr.go | 22 +++------------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 91ac6b0c..724c4831 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,4 +32,6 @@ jobs: skip_earthly_satellite: ${{ steps.install-local.outputs.cache-hit == false }} - name: Test run: | - forge release -vvv ./docs docs \ No newline at end of file + forge release -vvv ./docs docs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 23e37af2..b4bab96f 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -10,6 +10,7 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/project/providers" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" @@ -60,14 +61,18 @@ func (r *DocsReleaser) Release() error { return fmt.Errorf("failed to get PR number") } - prClient, err := github.NewPRClient(r.logger) + client, err := providers.NewGithubClient(r.project, r.logger) if err != nil { - return fmt.Errorf("failed to create PR client: %w", err) + return fmt.Errorf("failed to create github client: %w", err) } + prClient := github.NewPRClient(client, r.logger) owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] - prClient.PostComment(owner, repo, pr, "Hello, world!") + + if err := prClient.PostComment(owner, repo, pr, "Hello, world!"); err != nil { + return fmt.Errorf("failed to post comment to PR: %w", err) + } } // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { diff --git a/lib/tools/git/github/pr.go b/lib/tools/git/github/pr.go index f141cf6a..fd66d1a6 100644 --- a/lib/tools/git/github/pr.go +++ b/lib/tools/git/github/pr.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "log/slog" - "os" "github.com/google/go-github/v66/github" ) @@ -57,24 +56,9 @@ func (p *PRClient) PostComment(owner, repo string, prNumber int, body string) er return nil } -// NewPRClient creates a new PRClient with authentication from environment. -func NewPRClient(logger *slog.Logger) (*PRClient, error) { - token := os.Getenv("GITHUB_TOKEN") - if token == "" { - return nil, ErrNoGitHubToken - } - - client := github.NewClient(nil).WithAuthToken(token) - - return &PRClient{ - client: client, - logger: logger, - }, nil -} - -// NewCustomPRClient creates a new PRClient with a custom GitHub client. -func NewCustomPRClient(client *github.Client, logger *slog.Logger) *PRClient { - return &PRClient{ +// NewPRClient creates a new PRClient with a Github client. +func NewPRClient(client *github.Client, logger *slog.Logger) PRClient { + return PRClient{ client: client, logger: logger, } From 86f3085aa782ae9be806be64b7b273eb558b98ee Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:21:09 -0700 Subject: [PATCH 06/29] wip: testing --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 724c4831..64a5fc47 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,7 @@ permissions: id-token: write contents: write packages: write + pull-requests: write jobs: ci: From 4183cce9d719eaf40cf43cc1ea1c5ab7b96213be Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:29:57 -0700 Subject: [PATCH 07/29] wip: testing --- cli/pkg/release/providers/docs.go | 27 ++++++++++----- lib/tools/git/github/pr.go | 55 +++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index b4bab96f..2d7b397d 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -40,14 +40,14 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { - r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) - if err := r.run(r.workdir); err != nil { - return fmt.Errorf("failed to run docs release target: %w", err) - } + // r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) + // if err := r.run(r.workdir); err != nil { + // return fmt.Errorf("failed to run docs release target: %w", err) + // } - if err := r.validateArtifacts(r.workdir); err != nil { - return fmt.Errorf("failed to validate artifacts: %w", err) - } + // if err := r.validateArtifacts(r.workdir); err != nil { + // return fmt.Errorf("failed to validate artifacts: %w", err) + // } if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { r.logger.Info("No release event is firing, skipping release") @@ -70,9 +70,18 @@ func (r *DocsReleaser) Release() error { owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] - if err := prClient.PostComment(owner, repo, pr, "Hello, world!"); err != nil { - return fmt.Errorf("failed to post comment to PR: %w", err) + comments, err := prClient.ListComments(owner, repo, pr) + if err != nil { + return fmt.Errorf("failed to list comments: %w", err) + } + + for _, comment := range comments { + r.logger.Info("Comment", "author", comment.Author, "body", comment.Body) } + + // if err := prClient.PostComment(owner, repo, pr, "Hello, world!"); err != nil { + // return fmt.Errorf("failed to post comment to PR: %w", err) + // } } // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { diff --git a/lib/tools/git/github/pr.go b/lib/tools/git/github/pr.go index fd66d1a6..3226dae6 100644 --- a/lib/tools/git/github/pr.go +++ b/lib/tools/git/github/pr.go @@ -20,16 +20,51 @@ type PRClient struct { logger *slog.Logger } -// CommentOptions contains options for posting a comment. -type CommentOptions struct { - // Body is the comment content - Body string - // CommitID is the specific commit to comment on (optional) - CommitID string - // Path is the file path to comment on (optional) - Path string - // Position is the line position in the file (optional) - Position int +// Comment represents the pared‑down information we care about. +type Comment struct { + Author string + Body string +} + +// ListComments lists comments for a pull request. +func (p *PRClient) ListComments(owner, repo string, prNumber int) ([]Comment, error) { + var all []Comment + ctx := context.Background() + opts := &github.IssueListCommentsOptions{ + ListOptions: github.ListOptions{PerPage: 100}, + } + + for { + p.logger.Debug("Fetching PR comments page", + "owner", owner, "repo", repo, "pr", prNumber, "page", opts.Page) + comments, resp, err := p.client.Issues.ListComments(ctx, owner, repo, prNumber, opts) + if err != nil { + return nil, fmt.Errorf("failed to list comments: %w", err) + } + + for _, c := range comments { + author := "" + if c.User != nil && c.User.Login != nil { + author = *c.User.Login + } + body := "" + if c.Body != nil { + body = *c.Body + } + all = append(all, Comment{ + Author: author, + Body: body, + }) + } + + // Break out when we've reached the last page. + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + + return all, nil } // PostComment posts a comment to a pull request. From 8f2a8cb63b0f069429b894ba1fa710052b90ebcb Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:49:18 -0700 Subject: [PATCH 08/29] wip: testing --- cli/pkg/release/providers/docs.go | 94 ++++++++++++++------ lib/schema/blueprint/global/cue_types_gen.go | 3 + lib/schema/blueprint/global/release.cue | 3 + 3 files changed, 73 insertions(+), 27 deletions(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 2d7b397d..76134077 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -3,6 +3,7 @@ package providers import ( "fmt" "log/slog" + "net/url" "strings" "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" @@ -18,6 +19,17 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/tools/git/github" ) +const ( + docsCommentPrefix = "" + bodyTemplate = ` +## 📚 Docs Preview + +The docs for this PR can be previewed at the following URL: + +%s +` +) + // DocsReleaserConfig is the configuration for the docs release. type DocsReleaserConfig struct { Name string `json:"name"` @@ -54,34 +66,10 @@ func (r *DocsReleaser) Release() error { return nil } - env := github.NewGithubEnv(r.logger) - if env.IsPR() { - pr := env.GetPRNumber() - if pr == 0 { - return fmt.Errorf("failed to get PR number") - } - - client, err := providers.NewGithubClient(r.project, r.logger) - if err != nil { - return fmt.Errorf("failed to create github client: %w", err) - } - - prClient := github.NewPRClient(client, r.logger) - owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] - repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] - - comments, err := prClient.ListComments(owner, repo, pr) - if err != nil { - return fmt.Errorf("failed to list comments: %w", err) - } - - for _, comment := range comments { - r.logger.Info("Comment", "author", comment.Author, "body", comment.Body) + if github.InCI() { + if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url); err != nil { + return fmt.Errorf("failed to post comment: %w", err) } - - // if err := prClient.PostComment(owner, repo, pr, "Hello, world!"); err != nil { - // return fmt.Errorf("failed to post comment to PR: %w", err) - // } } // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { @@ -142,6 +130,58 @@ func (r *DocsReleaser) generatePath() (string, error) { return s3Path + "/" + branch, nil } +func (r *DocsReleaser) postComment(baseURL string) error { + env := github.NewGithubEnv(r.logger) + if env.IsPR() { + pr := env.GetPRNumber() + if pr == 0 { + r.logger.Warn("No PR number found, skipping comment") + return nil + } + + client, err := providers.NewGithubClient(r.project, r.logger) + if err != nil { + return fmt.Errorf("failed to create github client: %w", err) + } + + prClient := github.NewPRClient(client, r.logger) + owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] + repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] + + comments, err := prClient.ListComments(owner, repo, pr) + if err != nil { + return fmt.Errorf("failed to list comments: %w", err) + } + + for _, comment := range comments { + r.logger.Info("Comment", "author", comment.Author, "body", comment.Body) + if comment.Author == "github-actions[bot]" && strings.Contains(comment.Body, docsCommentPrefix) { + r.logger.Info("Found existing comment, skipping ") + return nil + } + } + + branch, err := git.GetBranch(r.project.Repo) + if err != nil { + return fmt.Errorf("failed to get branch: %w", err) + } + + docURL, err := url.JoinPath(baseURL, branch) + if err != nil { + return fmt.Errorf("failed to join URL path: %w", err) + } + + body := fmt.Sprintf(bodyTemplate, docURL) + if err := prClient.PostComment(owner, repo, pr, body); err != nil { + return fmt.Errorf("failed to post comment to PR: %w", err) + } + } else { + r.logger.Info("No PR found, skipping comment") + } + + return nil +} + // run runs the docs release target. func (r *DocsReleaser) run(path string) error { return r.runner.RunTarget( diff --git a/lib/schema/blueprint/global/cue_types_gen.go b/lib/schema/blueprint/global/cue_types_gen.go index 32ec7c71..8ca5ee91 100644 --- a/lib/schema/blueprint/global/cue_types_gen.go +++ b/lib/schema/blueprint/global/cue_types_gen.go @@ -87,6 +87,9 @@ type DocsRelease struct { // Path is the subpath within the bucket to upload the docs to. Path string `json:"path,omitempty"` + + // URL is the base URL to the docs. + Url string `json:"url"` } type Repo struct { diff --git a/lib/schema/blueprint/global/release.cue b/lib/schema/blueprint/global/release.cue index 4e791fd3..10d59bfa 100644 --- a/lib/schema/blueprint/global/release.cue +++ b/lib/schema/blueprint/global/release.cue @@ -13,4 +13,7 @@ package global // Path is the subpath within the bucket to upload the docs to. path?: string | *"" + + // URL is the base URL to the docs. + url: string } From 1921452f39478b5deb52fca39fb8a2e5b9a594d9 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:52:38 -0700 Subject: [PATCH 09/29] wip: testing --- blueprint.cue | 1 + 1 file changed, 1 insertion(+) diff --git a/blueprint.cue b/blueprint.cue index a2a51a11..a3a18f73 100644 --- a/blueprint.cue +++ b/blueprint.cue @@ -12,6 +12,7 @@ global: { ] release: docs: { bucket: "docs.dev.projectcatalyst.io" + url: "https://docs.dev.projectcatalyst.io/" } providers: { aws: { From 1820337cfeaf40fd52c2e4ddff1f846d94a1c454 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 18:58:01 -0700 Subject: [PATCH 10/29] wip: testing --- cli/pkg/release/providers/docs.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 76134077..fa6e8478 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -66,22 +66,21 @@ func (r *DocsReleaser) Release() error { return nil } - if github.InCI() { - if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url); err != nil { - return fmt.Errorf("failed to post comment: %w", err) - } - } - // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { // return fmt.Errorf("global docs release configuration not found") // } + projectName := r.config.Name + if projectName == "" { + projectName = r.project.Name + } + // docsConfig := r.project.Blueprint.Global.Ci.Release.Docs // if docsConfig.Bucket == "" { // return fmt.Errorf("no S3 bucket specified in global docs configuration") // } - // s3Path, err := r.generatePath() + // s3Path, err := r.generatePath(projectName) // if err != nil { // return fmt.Errorf("failed to generate S3 path: %w", err) // } @@ -97,17 +96,18 @@ func (r *DocsReleaser) Release() error { // return fmt.Errorf("failed to upload docs to S3: %w", err) // } + if github.InCI() { + if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url); err != nil { + return fmt.Errorf("failed to post comment: %w", err) + } + } + r.logger.Info("Docs release complete") return nil } // generatePath generates the S3 path for the docs. -func (r *DocsReleaser) generatePath() (string, error) { - projectName := r.config.Name - if projectName == "" { - projectName = r.project.Name - } - +func (r *DocsReleaser) generatePath(projectName string) (string, error) { docsConfig := r.project.Blueprint.Global.Ci.Release.Docs if docsConfig.Bucket == "" { return "", fmt.Errorf("no S3 bucket specified in global docs configuration") @@ -130,7 +130,7 @@ func (r *DocsReleaser) generatePath() (string, error) { return s3Path + "/" + branch, nil } -func (r *DocsReleaser) postComment(baseURL string) error { +func (r *DocsReleaser) postComment(baseURL, name string) error { env := github.NewGithubEnv(r.logger) if env.IsPR() { pr := env.GetPRNumber() @@ -166,7 +166,7 @@ func (r *DocsReleaser) postComment(baseURL string) error { return fmt.Errorf("failed to get branch: %w", err) } - docURL, err := url.JoinPath(baseURL, branch) + docURL, err := url.JoinPath(baseURL, name, branch) if err != nil { return fmt.Errorf("failed to join URL path: %w", err) } From 9114c9e21ccdc1a93aae2711c3124a025a13ae84 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 19:00:07 -0700 Subject: [PATCH 11/29] wip: testing --- cli/pkg/release/providers/docs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index fa6e8478..b3569984 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -97,7 +97,7 @@ func (r *DocsReleaser) Release() error { // } if github.InCI() { - if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url); err != nil { + if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url, projectName); err != nil { return fmt.Errorf("failed to post comment: %w", err) } } From e24bbbb83a782f2a983d9c8dabca096ac956cbd8 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 19:06:34 -0700 Subject: [PATCH 12/29] wip: testing --- cli/pkg/release/providers/docs.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index b3569984..413b53f1 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -22,6 +22,7 @@ import ( const ( docsCommentPrefix = "" bodyTemplate = ` +%s ## 📚 Docs Preview The docs for this PR can be previewed at the following URL: @@ -171,7 +172,7 @@ func (r *DocsReleaser) postComment(baseURL, name string) error { return fmt.Errorf("failed to join URL path: %w", err) } - body := fmt.Sprintf(bodyTemplate, docURL) + body := fmt.Sprintf(bodyTemplate, docsCommentPrefix, docURL) if err := prClient.PostComment(owner, repo, pr, body); err != nil { return fmt.Errorf("failed to post comment to PR: %w", err) } From d4abe363508d6bcfa7199c5b5bd7089ddc7c3750 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 19:16:49 -0700 Subject: [PATCH 13/29] wip: cleanup --- .github/workflows/dogfood.yml | 1 + .github/workflows/test.yml | 38 --------------------- cli/pkg/release/providers/docs.go | 56 +++++++++++++++---------------- 3 files changed, 29 insertions(+), 66 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/dogfood.yml b/.github/workflows/dogfood.yml index b2c9900b..8ec384f6 100644 --- a/.github/workflows/dogfood.yml +++ b/.github/workflows/dogfood.yml @@ -10,6 +10,7 @@ permissions: id-token: write contents: write packages: write + pull-requests: write jobs: ci: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 64a5fc47..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Test - -on: - push: - branches: [master] - tags: ['**'] - pull_request: - -permissions: - id-token: write - contents: write - packages: write - pull-requests: write - -jobs: - ci: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install Local Forge - id: install-local - uses: input-output-hk/catalyst-forge/actions/install-local@master - - name: Check forge version - id: local - run: | - forge version - - name: Setup CI - uses: input-output-hk/catalyst-forge/actions/setup@master - with: - skip_docker: 'true' - skip_github: 'true' - skip_earthly_install: ${{ steps.install-local.outputs.cache-hit == false }} - skip_earthly_satellite: ${{ steps.install-local.outputs.cache-hit == false }} - - name: Test - run: | - forge release -vvv ./docs docs - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 413b53f1..384cea6a 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -4,6 +4,7 @@ import ( "fmt" "log/slog" "net/url" + "path/filepath" "strings" "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" @@ -53,49 +54,49 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { - // r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) - // if err := r.run(r.workdir); err != nil { - // return fmt.Errorf("failed to run docs release target: %w", err) - // } + r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) + if err := r.run(r.workdir); err != nil { + return fmt.Errorf("failed to run docs release target: %w", err) + } - // if err := r.validateArtifacts(r.workdir); err != nil { - // return fmt.Errorf("failed to validate artifacts: %w", err) - // } + if err := r.validateArtifacts(r.workdir); err != nil { + return fmt.Errorf("failed to validate artifacts: %w", err) + } if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { r.logger.Info("No release event is firing, skipping release") return nil } - // if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { - // return fmt.Errorf("global docs release configuration not found") - // } + if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { + return fmt.Errorf("global docs release configuration not found") + } projectName := r.config.Name if projectName == "" { projectName = r.project.Name } - // docsConfig := r.project.Blueprint.Global.Ci.Release.Docs - // if docsConfig.Bucket == "" { - // return fmt.Errorf("no S3 bucket specified in global docs configuration") - // } + docsConfig := r.project.Blueprint.Global.Ci.Release.Docs + if docsConfig.Bucket == "" { + return fmt.Errorf("no S3 bucket specified in global docs configuration") + } - // s3Path, err := r.generatePath(projectName) - // if err != nil { - // return fmt.Errorf("failed to generate S3 path: %w", err) - // } + s3Path, err := r.generatePath(projectName) + if err != nil { + return fmt.Errorf("failed to generate S3 path: %w", err) + } - // r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) - // if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { - // return fmt.Errorf("failed to clean existing docs from S3: %w", err) - // } + r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) + if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { + return fmt.Errorf("failed to clean existing docs from S3: %w", err) + } - // finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) - // r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) - // if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { - // return fmt.Errorf("failed to upload docs to S3: %w", err) - // } + finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) + r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) + if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { + return fmt.Errorf("failed to upload docs to S3: %w", err) + } if github.InCI() { if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url, projectName); err != nil { @@ -155,7 +156,6 @@ func (r *DocsReleaser) postComment(baseURL, name string) error { } for _, comment := range comments { - r.logger.Info("Comment", "author", comment.Author, "body", comment.Body) if comment.Author == "github-actions[bot]" && strings.Contains(comment.Body, docsCommentPrefix) { r.logger.Info("Found existing comment, skipping ") return nil From 6ed907f1d4c1bfe409174790a8ae9c18ceb13275 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 21:25:25 -0700 Subject: [PATCH 14/29] chore: adds test --- cli/pkg/release/providers/docs_test.go | 223 +++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 cli/pkg/release/providers/docs_test.go diff --git a/cli/pkg/release/providers/docs_test.go b/cli/pkg/release/providers/docs_test.go new file mode 100644 index 00000000..fd78c215 --- /dev/null +++ b/cli/pkg/release/providers/docs_test.go @@ -0,0 +1,223 @@ +package providers + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "testing" + + "cuelang.org/go/cue" + "github.com/aws/aws-sdk-go-v2/service/s3" + s3types "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" + earthlyMocks "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly/mocks" + eventsMocks "github.com/input-output-hk/catalyst-forge/cli/pkg/events/mocks" + "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" + awsMocks "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" + "github.com/input-output-hk/catalyst-forge/lib/project/project" + sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" + "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" + sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" + "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" + "github.com/input-output-hk/catalyst-forge/lib/tools/walker" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDocsReleaserRelease(t *testing.T) { + type testResult struct { + localFs fs.Filesystem + s3Fs fs.Filesystem + err error + } + + newProject := func(projectName, branch, bucket, docsPath string) project.Project { + repo := testutils.NewTestRepo(t) + require.NoError(t, repo.WriteFile("README.md", []byte("hello docs"))) + _, err := repo.Commit("initial commit") + require.NoError(t, err) + + return project.Project{ + Name: projectName, + Blueprint: sb.Blueprint{ + Global: &global.Global{ + Repo: &global.Repo{ + Name: "owner/repo", + DefaultBranch: branch, + }, + Ci: &global.CI{ + Release: &global.Release{ + Docs: &global.DocsRelease{ + Bucket: bucket, + Path: docsPath, + Url: "https://docs.example.com/", + }, + }, + }, + }, + Project: &sp.Project{ + Release: map[string]sp.Release{ + "docs": { + Target: "docs", + }, + }, + }, + }, + Repo: &repo, + } + } + + tests := []struct { + name string + project project.Project + releaseName string + files map[string]string + s3files map[string]string + validate func(*testing.T, testResult) + }{ + { + name: "full", + project: newProject("project", "master", "bucket", "prefix"), + releaseName: "test", + files: map[string]string{ + "index.html": "test docs", + }, + s3files: map[string]string{ + "test.html": "test", + }, + validate: func(t *testing.T, result testResult) { + assert.NoError(t, result.err) + + result.s3Fs.Walk("/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + fmt.Println(path) + return nil + }) + + exists, err := result.s3Fs.Exists("/bucket/prefix/test/index.html") + require.NoError(t, err) + assert.True(t, exists) + + exists, err = result.s3Fs.Exists("/bucket/prefix/test/test.html") + require.NoError(t, err) + assert.False(t, exists) + + content, err := result.s3Fs.ReadFile("/bucket/prefix/test/index.html") + require.NoError(t, err) + assert.Equal(t, "test docs", string(content)) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s3Fs := billy.NewInMemoryFs() + for name, content := range tt.s3files { + p := filepath.Join("/", + tt.project.Blueprint.Global.Ci.Release.Docs.Bucket, + tt.project.Blueprint.Global.Ci.Release.Docs.Path, + tt.releaseName, + name, + ) + fmt.Println(p) + require.NoError(t, s3Fs.WriteFile(p, []byte(content), 0o644)) + } + + mockAWSS3 := &awsMocks.AWSS3ClientMock{ + PutObjectFunc: func(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) { + bucket := *params.Bucket + key := *params.Key + + bucketDir := "/" + bucket + _ = s3Fs.MkdirAll(bucketDir, 0o755) + filePath := filepath.Join(bucketDir, key) + data, err := io.ReadAll(params.Body) + if err != nil { + return nil, err + } + + if err := s3Fs.MkdirAll(filepath.Dir(filePath), 0o755); err != nil { + return nil, err + } + + if err := s3Fs.WriteFile(filePath, data, 0o644); err != nil { + return nil, err + } + + return &s3.PutObjectOutput{}, nil + }, + DeleteObjectFunc: func(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) { + bucket := *params.Bucket + key := *params.Key + bucketDir := "/" + bucket + filePath := filepath.Join(bucketDir, key) + + _ = s3Fs.Remove(filePath) + + return &s3.DeleteObjectOutput{}, nil + }, + ListObjectsV2Func: func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) { + bucket := *params.Bucket + prefix := "" + if params.Prefix != nil { + prefix = *params.Prefix + } + bucketDir := "/" + bucket + + var contents []s3types.Object + _ = s3Fs.Walk(bucketDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return nil + } + + relPath, _ := filepath.Rel(bucketDir, path) + if !info.IsDir() && strings.HasPrefix(relPath, prefix) { + contents = append(contents, s3types.Object{Key: &relPath}) + } + + return nil + }) + + return &s3.ListObjectsV2Output{Contents: contents}, nil + }, + } + + localFs := billy.NewInMemoryFs() + for name, content := range tt.files { + p := filepath.Join("/", earthly.GetBuildPlatform(), name) + require.NoError(t, localFs.MkdirAll(filepath.Dir(p), 0o755)) + require.NoError(t, localFs.WriteFile(p, []byte(content), 0o644)) + } + + w := walker.NewCustomDefaultFSWalker(localFs, testutils.NewNoopLogger()) + s3Client := aws.NewCustomS3Client(mockAWSS3, &w, testutils.NewNoopLogger()) + releaser := &DocsReleaser{ + config: DocsReleaserConfig{Name: tt.releaseName}, + force: true, + fs: localFs, + handler: &eventsMocks.EventHandlerMock{FiringFunc: func(_ *project.Project, _ map[string]cue.Value) bool { return true }}, + logger: testutils.NewNoopLogger(), + project: &tt.project, + release: sp.Release{Target: "docs"}, + releaseName: "docs", + runner: &earthlyMocks.ProjectRunnerMock{RunTargetFunc: func(string, ...earthly.EarthlyExecutorOption) error { return nil }}, + s3: s3Client, + workdir: "/", + } + + err := releaser.Release() + tt.validate(t, testResult{ + localFs: localFs, + s3Fs: s3Fs, + err: err, + }) + }) + } +} From 029878aa983d97f7dbc2b77bbc9e3770109e74eb Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 22:09:12 -0700 Subject: [PATCH 15/29] wip: testing --- .github/workflows/ci.yml | 165 ++++++++++++++---------------- .github/workflows/docs.yml | 104 ------------------- cli/pkg/providers/aws/s3.go | 45 ++++++++ cli/pkg/release/providers/docs.go | 101 +++++++++++------- lib/tools/git/github/client.go | 155 ++++++++++++++++++++++++++++ lib/tools/git/github/pr.go | 100 ------------------ 6 files changed, 343 insertions(+), 327 deletions(-) delete mode 100644 .github/workflows/docs.yml create mode 100644 lib/tools/git/github/client.go delete mode 100644 lib/tools/git/github/pr.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b24ce3f..15a6d261 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,79 +75,70 @@ jobs: ${{ env.FORGE_REGEX_RELEASE }} ${{ env.FORGE_REGEX_PUBLISH }} ${{ env.FORGE_REGEX_NIGHTLY }} - check: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover] - if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} - - build: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check] - if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # check: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover] + # if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - package: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check, build] - if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # build: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check] + # if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - test: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check, build, package] - if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # package: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check, build] + # if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - nightly: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check, build, package] - if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # test: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check, build, package] + # if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - # docs: - # uses: input-output-hk/catalyst-forge/.github/workflows/docs.yml@ci/v1.8.1 - # needs: [discover, check, build, test] - # if: (fromJson(needs.discover.outputs.earthfiles)['^docs(-.*)?$'] != null) && !failure() && !cancelled() + # nightly: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check, build, package] + # if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^docs(-.*)?$']) }} + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} # secrets: # earthly_token: ${{ secrets.earthly_token }} release: uses: input-output-hk/catalyst-forge/.github/workflows/release.yml@master - needs: [discover, check, build, test] + #needs: [discover, check, build, test] + needs: [discover] if: (fromJson(needs.discover.outputs.releases)[0] != null) && !failure() && !cancelled() with: releases: ${{ needs.discover.outputs.releases }} @@ -157,29 +148,29 @@ jobs: secrets: earthly_token: ${{ secrets.earthly_token }} - deploy: - uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master - needs: [discover, check, build, test, release] - if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() - with: - deployments: ${{ needs.discover.outputs.deployments }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # deploy: + # uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master + # needs: [discover, check, build, test, release] + # if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() + # with: + # deployments: ${{ needs.discover.outputs.deployments }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - final: - needs: [check, build, package, test, nightly, release, deploy] - if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} - runs-on: ubuntu-latest - steps: - - name: Final - run: | - if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] - then - echo "Run failed" - exit 1 - else - echo "All done" - fi \ No newline at end of file + # final: + # needs: [check, build, package, test, nightly, release, deploy] + # if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} + # runs-on: ubuntu-latest + # steps: + # - name: Final + # run: | + # if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] + # then + # echo "Run failed" + # exit 1 + # else + # echo "All done" + # fi \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 80361cee..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,104 +0,0 @@ -on: - workflow_call: - inputs: - earthfiles: - description: | - A JSON list of Earthfile paths+targets to use for publishing - required: true - type: string - forge_version: - description: | - The version of the forge CLI to install (use 'local' for testing) - required: true - type: string - local: - description: Forces local mode - required: false - type: string - default: "false" - target_args: - description: Extra arguments to pass to the target (if command is "run") - required: false - type: string - default: "" - verbosity: - description: The verbosity level to use - required: false - type: string - default: "info" - secrets: - earthly_token: - description: Optional Earthly token used to login to Earthly cloud during local builds of Forge CLI - required: false -env: - OUTPUT: ${{ github.workspace }}/output - -jobs: - run: - name: ${{ matrix.earthfile }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - earthfile: ${{ fromJson(inputs.earthfiles) }} - steps: - - uses: actions/checkout@v4 - - name: Install Forge - uses: input-output-hk/catalyst-forge/actions/install@master - if: ${{ inputs.forge_version != 'local' }} - with: - version: ${{ inputs.forge_version }} - - name: Install Local Forge - uses: input-output-hk/catalyst-forge/actions/install-local@master - if: ${{ inputs.forge_version == 'local' }} - with: - earthly_token: ${{ secrets.earthly_token }} - - name: Check forge version - id: local - run: | - forge version - - if [[ "${{ inputs.forge_version }}" == "local" ]]; then - echo "skip=true" >> $GITHUB_OUTPUT - else - echo "skip=false" >> $GITHUB_OUTPUT - fi - - name: Setup CI - uses: input-output-hk/catalyst-forge/actions/setup@master - with: - skip_earthly: ${{ steps.local.outputs.skip }} - - name: Run - uses: input-output-hk/catalyst-forge/actions/run@master - with: - command: run - args: --artifact ${{ env.OUTPUT }} ${{ matrix.earthfile }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Set env - run: | - GIT_BRANCH=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} - if [[ $GIT_BRANCH == "${{ github.event.repository.default_branch }}" ]]; then - DEST_DIR="/" - { - echo 'CLEAN_EXCLUDE<> "$GITHUB_ENV" - else - DEST_DIR="/branch/${GIT_BRANCH//[^a-zA-Z0-9_]/_}" - echo "CLEAN_EXCLUDE="/nothing"" >> $GITHUB_ENV - fi - echo "GIT_BRANCH=$GIT_BRANCH" >> $GITHUB_ENV - echo "DEST_DIR=$DEST_DIR" >> $GITHUB_ENV - - name: Publish docs - uses: JamesIves/github-pages-deploy-action@v4.6.4 - with: - clean: true - clean-exclude: | - ${{ env.CLEAN_EXCLUDE }} - single-commit: true - target-folder: ${{ env.DEST_DIR }} - folder: ${{ env.OUTPUT }}/linux/amd64 \ No newline at end of file diff --git a/cli/pkg/providers/aws/s3.go b/cli/pkg/providers/aws/s3.go index 3dd1bdea..c1ac0635 100644 --- a/cli/pkg/providers/aws/s3.go +++ b/cli/pkg/providers/aws/s3.go @@ -7,6 +7,7 @@ import ( "log/slog" "mime" "path/filepath" + "strings" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go/aws" @@ -86,6 +87,50 @@ func (c *S3Client) DeleteDirectory(bucket, prefix string) error { return nil } +func (c *S3Client) ListImmediateChildren(bucket, prefix string) ([]string, error) { + if prefix != "" && !strings.HasSuffix(prefix, "/") { + prefix += "/" + } + + var children []string + seen := make(map[string]struct{}) + + input := &s3.ListObjectsV2Input{ + Bucket: aws.String(bucket), + Prefix: aws.String(prefix), + Delimiter: aws.String("/"), + } + + for { + out, err := c.client.ListObjectsV2(context.Background(), input) + if err != nil { + return nil, fmt.Errorf("list objects (prefix=%s): %w", prefix, err) + } + + for _, cp := range out.CommonPrefixes { + if cp.Prefix == nil { + continue + } + + name := strings.TrimSuffix(strings.TrimPrefix(*cp.Prefix, prefix), "/") + if name == "" { + continue + } + if _, ok := seen[name]; !ok { + seen[name] = struct{}{} + children = append(children, name) + } + } + + if out.IsTruncated != nil && !*out.IsTruncated { + break + } + input.ContinuationToken = out.NextContinuationToken + } + + return children, nil +} + // UploadDirectory uploads all files from a local directory to S3. func (c *S3Client) UploadDirectory(bucket, prefix string, localPath string, fs fs.Filesystem) error { if c.walker == nil { diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 384cea6a..49bcb705 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -12,7 +12,6 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/providers" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" @@ -54,19 +53,19 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { - r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) - if err := r.run(r.workdir); err != nil { - return fmt.Errorf("failed to run docs release target: %w", err) - } + // r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) + // if err := r.run(r.workdir); err != nil { + // return fmt.Errorf("failed to run docs release target: %w", err) + // } - if err := r.validateArtifacts(r.workdir); err != nil { - return fmt.Errorf("failed to validate artifacts: %w", err) - } + // if err := r.validateArtifacts(r.workdir); err != nil { + // return fmt.Errorf("failed to validate artifacts: %w", err) + // } - if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { - r.logger.Info("No release event is firing, skipping release") - return nil - } + // if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { + // r.logger.Info("No release event is firing, skipping release") + // return nil + // } if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { return fmt.Errorf("global docs release configuration not found") @@ -87,27 +86,66 @@ func (r *DocsReleaser) Release() error { return fmt.Errorf("failed to generate S3 path: %w", err) } - r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) - if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { - return fmt.Errorf("failed to clean existing docs from S3: %w", err) + children, err := r.s3.ListImmediateChildren(docsConfig.Bucket, filepath.Dir(s3Path)) + if err != nil { + return fmt.Errorf("failed to list immediate children: %w", err) } - finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) - r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) - if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { - return fmt.Errorf("failed to upload docs to S3: %w", err) + for _, child := range children { + r.logger.Info("Found child", "child", child) } - if github.InCI() { - if err := r.postComment(r.project.Blueprint.Global.Ci.Release.Docs.Url, projectName); err != nil { - return fmt.Errorf("failed to post comment: %w", err) - } - } + // r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) + // if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { + // return fmt.Errorf("failed to clean existing docs from S3: %w", err) + // } + + // finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) + // r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) + // if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { + // return fmt.Errorf("failed to upload docs to S3: %w", err) + // } + + // if github.InCI() { + // client, err := providers.NewGithubClient(r.project, r.logger) + // if err != nil { + // return fmt.Errorf("failed to create github client: %w", err) + // } + + // owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] + // repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] + // gc := github.NewGithubClient(owner, repo, client, r.logger) + // url := r.project.Blueprint.Global.Ci.Release.Docs.Url + + // if err := r.postComment(gc, url, projectName); err != nil { + // return fmt.Errorf("failed to post comment: %w", err) + // } + + // branch, err := git.GetBranch(r.project.Repo) + // if err != nil { + // return fmt.Errorf("failed to get branch: %w", err) + // } + + // if branch != r.project.Blueprint.Global.Repo.DefaultBranch { + // if err := r.cleanupBranches(gc, docsConfig.Bucket, filepath.Dir(s3Path)); err != nil { + // return fmt.Errorf("failed to cleanup branches: %w", err) + // } + // } + // } r.logger.Info("Docs release complete") return nil } +// func (r *DocsReleaser) cleanupBranches(client github.GithubClient, bucket, path string) error { +// branches, err := client.ListBranches() +// if err != nil { +// return fmt.Errorf("failed to list GitHub branches: %w", err) +// } + +// return nil +// } + // generatePath generates the S3 path for the docs. func (r *DocsReleaser) generatePath(projectName string) (string, error) { docsConfig := r.project.Blueprint.Global.Ci.Release.Docs @@ -132,7 +170,7 @@ func (r *DocsReleaser) generatePath(projectName string) (string, error) { return s3Path + "/" + branch, nil } -func (r *DocsReleaser) postComment(baseURL, name string) error { +func (r *DocsReleaser) postComment(client github.GithubClient, baseURL, name string) error { env := github.NewGithubEnv(r.logger) if env.IsPR() { pr := env.GetPRNumber() @@ -141,16 +179,7 @@ func (r *DocsReleaser) postComment(baseURL, name string) error { return nil } - client, err := providers.NewGithubClient(r.project, r.logger) - if err != nil { - return fmt.Errorf("failed to create github client: %w", err) - } - - prClient := github.NewPRClient(client, r.logger) - owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] - repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] - - comments, err := prClient.ListComments(owner, repo, pr) + comments, err := client.ListPullRequestComments(pr) if err != nil { return fmt.Errorf("failed to list comments: %w", err) } @@ -173,7 +202,7 @@ func (r *DocsReleaser) postComment(baseURL, name string) error { } body := fmt.Sprintf(bodyTemplate, docsCommentPrefix, docURL) - if err := prClient.PostComment(owner, repo, pr, body); err != nil { + if err := client.PostPullRequestComment(pr, body); err != nil { return fmt.Errorf("failed to post comment to PR: %w", err) } } else { diff --git a/lib/tools/git/github/client.go b/lib/tools/git/github/client.go new file mode 100644 index 00000000..7d8aab42 --- /dev/null +++ b/lib/tools/git/github/client.go @@ -0,0 +1,155 @@ +package github + +import ( + "context" + "fmt" + "log/slog" + + "github.com/google/go-github/v66/github" +) + +var ( + ErrNoGitHubToken = fmt.Errorf("no GitHub token found") + ErrNoRepository = fmt.Errorf("no repository information found") + ErrInvalidPR = fmt.Errorf("invalid pull request number") +) + +// GithubClient is a wrapper around the github client. +type GithubClient struct { + client *github.Client + logger *slog.Logger + owner string + repoName string +} + +// Branch represents a Git branch in the repository. +type Branch struct { + Name string + CommitSHA string + Protected bool +} + +// PullRequestComment is a comment on a pull request. +type PullRequestComment struct { + Author string + Body string +} + +// ListPullRequestComments lists comments for a pull request. +func (g *GithubClient) ListPullRequestComments(prNumber int) ([]PullRequestComment, error) { + var all []PullRequestComment + ctx := context.Background() + opts := &github.IssueListCommentsOptions{ + ListOptions: github.ListOptions{PerPage: 100}, + } + + for { + g.logger.Debug("Fetching PR comments page", + "owner", g.owner, "repo", g.repoName, "pr", prNumber, "page", opts.Page) + comments, resp, err := g.client.Issues.ListComments(ctx, g.owner, g.repoName, prNumber, opts) + if err != nil { + return nil, fmt.Errorf("failed to list comments: %w", err) + } + + for _, c := range comments { + author := "" + if c.User != nil && c.User.Login != nil { + author = *c.User.Login + } + body := "" + if c.Body != nil { + body = *c.Body + } + all = append(all, PullRequestComment{ + Author: author, + Body: body, + }) + } + + // Break out when we've reached the last page. + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + + return all, nil +} + +// PostPullRequestComment posts a comment to a pull request. +func (g *GithubClient) PostPullRequestComment(prNumber int, body string) error { + if prNumber <= 0 { + return ErrInvalidPR + } + + if body == "" { + return fmt.Errorf("comment body cannot be empty") + } + + comment := &github.IssueComment{ + Body: &body, + } + + g.logger.Debug("Posting comment to PR", "owner", g.owner, "repo", g.repoName, "pr", prNumber) + _, _, err := g.client.Issues.CreateComment(context.Background(), g.owner, g.repoName, prNumber, comment) + if err != nil { + return fmt.Errorf("failed to post comment: %w", err) + } + + g.logger.Info("Successfully posted comment to PR", "owner", g.owner, "repo", g.repoName, "pr", prNumber) + return nil +} + +// ListBranches lists all branches in the repository. +func (g *GithubClient) ListBranches() ([]Branch, error) { + var all []Branch + ctx := context.Background() + opts := &github.BranchListOptions{ + ListOptions: github.ListOptions{PerPage: 100}, + } + + for { + g.logger.Debug("Fetching branches page", + "owner", g.owner, "repo", g.repoName, "page", opts.Page) + branches, resp, err := g.client.Repositories.ListBranches(ctx, g.owner, g.repoName, opts) + if err != nil { + return nil, fmt.Errorf("failed to list branches: %w", err) + } + + for _, b := range branches { + name := "" + if b.Name != nil { + name = *b.Name + } + + commitSHA := "" + if b.Commit != nil && b.Commit.SHA != nil { + commitSHA = *b.Commit.SHA + } + + all = append(all, Branch{ + Name: name, + CommitSHA: commitSHA, + Protected: b.GetProtected(), + }) + } + + // Break out when we've reached the last page. + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + + return all, nil +} + +// NewGithubClient creates a new GithubClient with a *github.Client and repository owner and name. +func NewGithubClient(owner, repoName string, client *github.Client, logger *slog.Logger) GithubClient { + return GithubClient{ + client: client, + logger: logger, + owner: owner, + repoName: repoName, + } +} diff --git a/lib/tools/git/github/pr.go b/lib/tools/git/github/pr.go deleted file mode 100644 index 3226dae6..00000000 --- a/lib/tools/git/github/pr.go +++ /dev/null @@ -1,100 +0,0 @@ -package github - -import ( - "context" - "fmt" - "log/slog" - - "github.com/google/go-github/v66/github" -) - -var ( - ErrNoGitHubToken = fmt.Errorf("no GitHub token found") - ErrNoRepository = fmt.Errorf("no repository information found") - ErrInvalidPR = fmt.Errorf("invalid pull request number") -) - -// PRClient provides functionality for interacting with pull requests. -type PRClient struct { - client *github.Client - logger *slog.Logger -} - -// Comment represents the pared‑down information we care about. -type Comment struct { - Author string - Body string -} - -// ListComments lists comments for a pull request. -func (p *PRClient) ListComments(owner, repo string, prNumber int) ([]Comment, error) { - var all []Comment - ctx := context.Background() - opts := &github.IssueListCommentsOptions{ - ListOptions: github.ListOptions{PerPage: 100}, - } - - for { - p.logger.Debug("Fetching PR comments page", - "owner", owner, "repo", repo, "pr", prNumber, "page", opts.Page) - comments, resp, err := p.client.Issues.ListComments(ctx, owner, repo, prNumber, opts) - if err != nil { - return nil, fmt.Errorf("failed to list comments: %w", err) - } - - for _, c := range comments { - author := "" - if c.User != nil && c.User.Login != nil { - author = *c.User.Login - } - body := "" - if c.Body != nil { - body = *c.Body - } - all = append(all, Comment{ - Author: author, - Body: body, - }) - } - - // Break out when we've reached the last page. - if resp.NextPage == 0 { - break - } - opts.Page = resp.NextPage - } - - return all, nil -} - -// PostComment posts a comment to a pull request. -func (p *PRClient) PostComment(owner, repo string, prNumber int, body string) error { - if prNumber <= 0 { - return ErrInvalidPR - } - - if body == "" { - return fmt.Errorf("comment body cannot be empty") - } - - comment := &github.IssueComment{ - Body: &body, - } - - p.logger.Debug("Posting comment to PR", "owner", owner, "repo", repo, "pr", prNumber) - _, _, err := p.client.Issues.CreateComment(context.Background(), owner, repo, prNumber, comment) - if err != nil { - return fmt.Errorf("failed to post comment: %w", err) - } - - p.logger.Info("Successfully posted comment to PR", "owner", owner, "repo", repo, "pr", prNumber) - return nil -} - -// NewPRClient creates a new PRClient with a Github client. -func NewPRClient(client *github.Client, logger *slog.Logger) PRClient { - return PRClient{ - client: client, - logger: logger, - } -} From 7a8dd03a85a08d0358f5a2b956aa301ef169b88f Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 22:36:45 -0700 Subject: [PATCH 16/29] wip: testing --- cli/pkg/providers/aws/s3.go | 13 ++- cli/pkg/release/providers/docs.go | 155 ++++++++++++++++++------------ 2 files changed, 104 insertions(+), 64 deletions(-) diff --git a/cli/pkg/providers/aws/s3.go b/cli/pkg/providers/aws/s3.go index c1ac0635..985c827f 100644 --- a/cli/pkg/providers/aws/s3.go +++ b/cli/pkg/providers/aws/s3.go @@ -7,6 +7,7 @@ import ( "log/slog" "mime" "path/filepath" + "regexp" "strings" "github.com/aws/aws-sdk-go-v2/service/s3" @@ -66,7 +67,8 @@ func (c *S3Client) DeleteFile(bucket, key string) error { } // DeleteDirectory deletes all objects in a directory (prefix) from S3. -func (c *S3Client) DeleteDirectory(bucket, prefix string) error { +// exclude is a list of regexes to exclude from deletion. +func (c *S3Client) DeleteDirectory(bucket, prefix string, exclude []string) error { listInput := &s3.ListObjectsV2Input{ Bucket: aws.String(bucket), Prefix: aws.String(prefix), @@ -78,6 +80,15 @@ func (c *S3Client) DeleteDirectory(bucket, prefix string) error { } for _, object := range listOutput.Contents { + for _, exclude := range exclude { + match, err := regexp.MatchString(exclude, *object.Key) + if err != nil { + return fmt.Errorf("failed to match regex: %w", err) + } else if match { + continue + } + } + if err := c.DeleteFile(bucket, *object.Key); err != nil { return fmt.Errorf("failed to delete object %s: %w", *object.Key, err) } diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 49bcb705..16af5835 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -5,6 +5,7 @@ import ( "log/slog" "net/url" "path/filepath" + "slices" "strings" "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" @@ -12,6 +13,7 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/project/providers" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" @@ -53,19 +55,19 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { - // r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) - // if err := r.run(r.workdir); err != nil { - // return fmt.Errorf("failed to run docs release target: %w", err) - // } + r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) + if err := r.run(r.workdir); err != nil { + return fmt.Errorf("failed to run docs release target: %w", err) + } - // if err := r.validateArtifacts(r.workdir); err != nil { - // return fmt.Errorf("failed to validate artifacts: %w", err) - // } + if err := r.validateArtifacts(r.workdir); err != nil { + return fmt.Errorf("failed to validate artifacts: %w", err) + } - // if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { - // r.logger.Info("No release event is firing, skipping release") - // return nil - // } + if !r.handler.Firing(r.project, r.project.GetReleaseEvents(r.releaseName)) && !r.force { + r.logger.Info("No release event is firing, skipping release") + return nil + } if r.project.Blueprint.Global.Ci == nil || r.project.Blueprint.Global.Ci.Release == nil || r.project.Blueprint.Global.Ci.Release.Docs == nil { return fmt.Errorf("global docs release configuration not found") @@ -86,65 +88,76 @@ func (r *DocsReleaser) Release() error { return fmt.Errorf("failed to generate S3 path: %w", err) } - children, err := r.s3.ListImmediateChildren(docsConfig.Bucket, filepath.Dir(s3Path)) - if err != nil { - return fmt.Errorf("failed to list immediate children: %w", err) + r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) + if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path, []string{".*/branches/.*"}); err != nil { + return fmt.Errorf("failed to clean existing docs from S3: %w", err) } - for _, child := range children { - r.logger.Info("Found child", "child", child) + finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) + r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) + if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { + return fmt.Errorf("failed to upload docs to S3: %w", err) } - // r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) - // if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path); err != nil { - // return fmt.Errorf("failed to clean existing docs from S3: %w", err) - // } - - // finalPath := filepath.Join(r.workdir, earthly.GetBuildPlatform()) - // r.logger.Info("Uploading docs to S3", "bucket", docsConfig.Bucket, "path", s3Path) - // if err := r.s3.UploadDirectory(docsConfig.Bucket, s3Path, finalPath, r.fs); err != nil { - // return fmt.Errorf("failed to upload docs to S3: %w", err) - // } - - // if github.InCI() { - // client, err := providers.NewGithubClient(r.project, r.logger) - // if err != nil { - // return fmt.Errorf("failed to create github client: %w", err) - // } - - // owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] - // repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] - // gc := github.NewGithubClient(owner, repo, client, r.logger) - // url := r.project.Blueprint.Global.Ci.Release.Docs.Url - - // if err := r.postComment(gc, url, projectName); err != nil { - // return fmt.Errorf("failed to post comment: %w", err) - // } - - // branch, err := git.GetBranch(r.project.Repo) - // if err != nil { - // return fmt.Errorf("failed to get branch: %w", err) - // } - - // if branch != r.project.Blueprint.Global.Repo.DefaultBranch { - // if err := r.cleanupBranches(gc, docsConfig.Bucket, filepath.Dir(s3Path)); err != nil { - // return fmt.Errorf("failed to cleanup branches: %w", err) - // } - // } - // } + if github.InCI() { + client, err := providers.NewGithubClient(r.project, r.logger) + if err != nil { + return fmt.Errorf("failed to create github client: %w", err) + } + + owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] + repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] + gc := github.NewGithubClient(owner, repo, client, r.logger) + url := r.project.Blueprint.Global.Ci.Release.Docs.Url + + if err := r.postComment(gc, url, projectName); err != nil { + return fmt.Errorf("failed to post comment: %w", err) + } + + isDefault, err := r.isDefaultBranch() + if err != nil { + return fmt.Errorf("failed to check if branch is default: %w", err) + } + + if isDefault { + if err := r.cleanupBranches(gc, docsConfig.Bucket, filepath.Join(s3Path, "branches")); err != nil { + return fmt.Errorf("failed to cleanup branches: %w", err) + } + } + } r.logger.Info("Docs release complete") return nil } -// func (r *DocsReleaser) cleanupBranches(client github.GithubClient, bucket, path string) error { -// branches, err := client.ListBranches() -// if err != nil { -// return fmt.Errorf("failed to list GitHub branches: %w", err) -// } +// cleanupBranches deletes branches from S3 that are no longer present in GitHub. +func (r *DocsReleaser) cleanupBranches(client github.GithubClient, bucket, path string) error { + branches, err := client.ListBranches() + if err != nil { + return fmt.Errorf("failed to list GitHub branches: %w", err) + } + + var branchNames []string + for _, branch := range branches { + branchNames = append(branchNames, branch.Name) + } + + children, err := r.s3.ListImmediateChildren(bucket, path) + if err != nil { + return fmt.Errorf("failed to list immediate children: %w", err) + } + + for _, child := range children { + if !slices.Contains(branchNames, child) { + r.logger.Info("Deleting branch", "branch", child) + if err := r.s3.DeleteDirectory(bucket, filepath.Join(path, child), nil); err != nil { + return fmt.Errorf("failed to delete branch: %w", err) + } + } + } -// return nil -// } + return nil +} // generatePath generates the S3 path for the docs. func (r *DocsReleaser) generatePath(projectName string) (string, error) { @@ -155,7 +168,7 @@ func (r *DocsReleaser) generatePath(projectName string) (string, error) { s3Path := projectName if docsConfig.Path != "" { - s3Path = docsConfig.Path + "/" + projectName + s3Path = filepath.Join(docsConfig.Path, projectName) } branch, err := git.GetBranch(r.project.Repo) @@ -167,9 +180,20 @@ func (r *DocsReleaser) generatePath(projectName string) (string, error) { return s3Path, nil } - return s3Path + "/" + branch, nil + return filepath.Join(s3Path, "branches", branch), nil +} + +// isDefaultBranch returns true if the current branch is the default branch. +func (r *DocsReleaser) isDefaultBranch() (bool, error) { + branch, err := git.GetBranch(r.project.Repo) + if err != nil { + return false, fmt.Errorf("failed to get branch: %w", err) + } + + return branch == r.project.Blueprint.Global.Repo.DefaultBranch, nil } +// postComment posts a comment to the PR. func (r *DocsReleaser) postComment(client github.GithubClient, baseURL, name string) error { env := github.NewGithubEnv(r.logger) if env.IsPR() { @@ -196,7 +220,12 @@ func (r *DocsReleaser) postComment(client github.GithubClient, baseURL, name str return fmt.Errorf("failed to get branch: %w", err) } - docURL, err := url.JoinPath(baseURL, name, branch) + var docURL string + if branch == r.project.Blueprint.Global.Repo.DefaultBranch { + docURL, err = url.JoinPath(baseURL, name) + } else { + docURL, err = url.JoinPath(baseURL, name, "branches", branch) + } if err != nil { return fmt.Errorf("failed to join URL path: %w", err) } From f4ec140e4ebe0c5223752d2aa3c283d53a90d1d2 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 22:44:29 -0700 Subject: [PATCH 17/29] wip: testing --- cli/pkg/release/providers/docs.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 16af5835..c645f513 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -55,6 +55,13 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { + // Testing + branch, err := git.GetBranch(r.project.Repo) + if err != nil { + return fmt.Errorf("failed to get branch: %w", err) + } + r.project.Blueprint.Global.Repo.DefaultBranch = branch + r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) if err := r.run(r.workdir); err != nil { return fmt.Errorf("failed to run docs release target: %w", err) From e49e99044f492d2b7b2ef899bf5f10cc27c33fff Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 22:54:54 -0700 Subject: [PATCH 18/29] wip: testing --- cli/pkg/providers/aws/s3.go | 21 ++++++++++++--------- cli/pkg/release/providers/docs.go | 10 +++++----- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/cli/pkg/providers/aws/s3.go b/cli/pkg/providers/aws/s3.go index 985c827f..bee8d77e 100644 --- a/cli/pkg/providers/aws/s3.go +++ b/cli/pkg/providers/aws/s3.go @@ -79,18 +79,21 @@ func (c *S3Client) DeleteDirectory(bucket, prefix string, exclude []string) erro return fmt.Errorf("failed to list objects in S3: %w", err) } - for _, object := range listOutput.Contents { - for _, exclude := range exclude { - match, err := regexp.MatchString(exclude, *object.Key) - if err != nil { - return fmt.Errorf("failed to match regex: %w", err) - } else if match { - continue + for _, obj := range listOutput.Contents { + skip := false + for _, pat := range exclude { + if regexp.MustCompile(pat).MatchString(*obj.Key) { + skip = true + break } } + if skip { + c.logger.Debug("Skipping delete (excluded)", "key", *obj.Key) + continue + } - if err := c.DeleteFile(bucket, *object.Key); err != nil { - return fmt.Errorf("failed to delete object %s: %w", *object.Key, err) + if err := c.DeleteFile(bucket, *obj.Key); err != nil { + return fmt.Errorf("failed to delete object %s: %w", *obj.Key, err) } } diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index c645f513..b37b2efa 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -56,11 +56,11 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { // Testing - branch, err := git.GetBranch(r.project.Repo) - if err != nil { - return fmt.Errorf("failed to get branch: %w", err) - } - r.project.Blueprint.Global.Repo.DefaultBranch = branch + // branch, err := git.GetBranch(r.project.Repo) + // if err != nil { + // return fmt.Errorf("failed to get branch: %w", err) + // } + // r.project.Blueprint.Global.Repo.DefaultBranch = branch r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) if err := r.run(r.workdir); err != nil { From db6f84b631e9fd6a72d166d1c4ef5e6a04cff9a7 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Wed, 23 Jul 2025 22:58:22 -0700 Subject: [PATCH 19/29] wip: testing --- cli/pkg/release/providers/docs.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index b37b2efa..c645f513 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -56,11 +56,11 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { // Testing - // branch, err := git.GetBranch(r.project.Repo) - // if err != nil { - // return fmt.Errorf("failed to get branch: %w", err) - // } - // r.project.Blueprint.Global.Repo.DefaultBranch = branch + branch, err := git.GetBranch(r.project.Repo) + if err != nil { + return fmt.Errorf("failed to get branch: %w", err) + } + r.project.Blueprint.Global.Repo.DefaultBranch = branch r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) if err := r.run(r.workdir); err != nil { From 056b00b54a85ff73deb742f7189708df79f2a65a Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 09:03:33 -0700 Subject: [PATCH 20/29] wip: testing --- cli/pkg/release/providers/docs.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index c645f513..80727a0b 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -149,11 +149,15 @@ func (r *DocsReleaser) cleanupBranches(client github.GithubClient, bucket, path branchNames = append(branchNames, branch.Name) } + fmt.Printf("branchNames: %v\n", branchNames) + children, err := r.s3.ListImmediateChildren(bucket, path) if err != nil { return fmt.Errorf("failed to list immediate children: %w", err) } + fmt.Printf("children: %v\n", children) + for _, child := range children { if !slices.Contains(branchNames, child) { r.logger.Info("Deleting branch", "branch", child) From 966d447fc582b53778bf870a9c2eb33fa2179aa3 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 09:15:33 -0700 Subject: [PATCH 21/29] wip: cleanup --- .github/workflows/ci.yml | 163 +++++++++++++++--------------- cli/pkg/release/providers/docs.go | 11 -- 2 files changed, 81 insertions(+), 93 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15a6d261..1b1fe086 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,70 +75,69 @@ jobs: ${{ env.FORGE_REGEX_RELEASE }} ${{ env.FORGE_REGEX_PUBLISH }} ${{ env.FORGE_REGEX_NIGHTLY }} - # check: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover] - # if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + check: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover] + if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # build: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check] - # if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + build: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check] + if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # package: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check, build] - # if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + package: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check, build] + if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # test: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check, build, package] - # if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + test: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check, build, package] + if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # nightly: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check, build, package] - # if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + nightly: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check, build, package] + if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} release: uses: input-output-hk/catalyst-forge/.github/workflows/release.yml@master - #needs: [discover, check, build, test] - needs: [discover] + needs: [discover, check, build, test] if: (fromJson(needs.discover.outputs.releases)[0] != null) && !failure() && !cancelled() with: releases: ${{ needs.discover.outputs.releases }} @@ -148,29 +147,29 @@ jobs: secrets: earthly_token: ${{ secrets.earthly_token }} - # deploy: - # uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master - # needs: [discover, check, build, test, release] - # if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() - # with: - # deployments: ${{ needs.discover.outputs.deployments }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + deploy: + uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master + needs: [discover, check, build, test, release] + if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() + with: + deployments: ${{ needs.discover.outputs.deployments }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # final: - # needs: [check, build, package, test, nightly, release, deploy] - # if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} - # runs-on: ubuntu-latest - # steps: - # - name: Final - # run: | - # if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] - # then - # echo "Run failed" - # exit 1 - # else - # echo "All done" - # fi \ No newline at end of file + final: + needs: [check, build, package, test, nightly, release, deploy] + if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} + runs-on: ubuntu-latest + steps: + - name: Final + run: | + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] + then + echo "Run failed" + exit 1 + else + echo "All done" + fi \ No newline at end of file diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 80727a0b..16af5835 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -55,13 +55,6 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { - // Testing - branch, err := git.GetBranch(r.project.Repo) - if err != nil { - return fmt.Errorf("failed to get branch: %w", err) - } - r.project.Blueprint.Global.Repo.DefaultBranch = branch - r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) if err := r.run(r.workdir); err != nil { return fmt.Errorf("failed to run docs release target: %w", err) @@ -149,15 +142,11 @@ func (r *DocsReleaser) cleanupBranches(client github.GithubClient, bucket, path branchNames = append(branchNames, branch.Name) } - fmt.Printf("branchNames: %v\n", branchNames) - children, err := r.s3.ListImmediateChildren(bucket, path) if err != nil { return fmt.Errorf("failed to list immediate children: %w", err) } - fmt.Printf("children: %v\n", children) - for _, child := range children { if !slices.Contains(branchNames, child) { r.logger.Info("Deleting branch", "branch", child) From d013f8cac4a5abeebb5df547b8c89ea95191cce2 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 17:20:16 -0700 Subject: [PATCH 22/29] chore: refactors common packages --- cli/Earthfile | 4 +- cli/cmd/cmds/configure_satellite.go | 2 +- cli/cmd/cmds/secret.go | 2 +- cli/cmd/main.go | 2 +- cli/go.mod | 54 +-- cli/go.sum | 88 +++-- cli/pkg/earthly/earthly.go | 2 +- cli/pkg/earthly/earthly_test.go | 4 +- cli/pkg/earthly/project.go | 2 +- cli/pkg/earthly/project_test.go | 4 +- cli/pkg/earthly/satellite/satellite.go | 8 +- cli/pkg/earthly/satellite/satellite_test.go | 4 +- cli/pkg/events/merge.go | 2 +- cli/pkg/events/tag_test.go | 2 +- cli/pkg/providers/kcl/client.go | 73 ---- cli/pkg/providers/kcl/mocks/kcl.go | 108 ------ cli/pkg/release/providers/common.go | 4 +- cli/pkg/release/providers/common_test.go | 4 +- cli/pkg/release/providers/cue.go | 2 +- cli/pkg/release/providers/cue_test.go | 4 +- cli/pkg/release/providers/docker.go | 2 +- cli/pkg/release/providers/docker_test.go | 4 +- cli/pkg/release/providers/docs.go | 49 +-- cli/pkg/release/providers/docs_test.go | 4 +- cli/pkg/release/providers/github.go | 47 +-- cli/pkg/release/providers/github_test.go | 97 ++--- cli/pkg/release/providers/kcl.go | 2 +- cli/pkg/release/providers/kcl_test.go | 4 +- cli/pkg/run/context.go | 2 +- cli/tui/ci/app.go | 2 +- cli/tui/ci/ci.go | 2 +- lib/project/Earthfile | 4 +- lib/project/deployment/deployer/deployer.go | 6 +- lib/project/deployment/module.go | 2 +- lib/project/deployment/module_test.go | 4 +- lib/project/go.mod | 40 ++- lib/project/go.sum | 60 ++-- lib/project/project/loader.go | 4 +- lib/project/project/project.go | 2 +- lib/project/project/runtime.go | 20 +- lib/project/providers/github.go | 59 ---- lib/project/utils/pointers.go | 16 - lib/project/utils/test/secrets.go | 4 +- lib/providers/.earthlyignore | 4 + lib/providers/Earthfile | 40 +++ lib/providers/LICENSE-APACHE | 201 +++++++++++ lib/providers/LICENSE-MIT | 25 ++ {cli/pkg => lib}/providers/aws/common.go | 0 {cli/pkg => lib}/providers/aws/ecr.go | 7 +- {cli/pkg => lib}/providers/aws/ecr_test.go | 38 +- {cli/pkg => lib}/providers/aws/mocks/ecr.go | 0 {cli/pkg => lib}/providers/aws/mocks/s3.go | 0 {cli/pkg => lib}/providers/aws/s3.go | 0 lib/providers/blueprint.cue | 1 + .../earthly}/earthly.go | 4 +- lib/{tools => providers}/git/branch.go | 9 +- .../providers => providers/git}/git.go | 4 +- lib/{tools => providers}/git/tag.go | 9 +- lib/{tools => providers}/git/util.go | 0 lib/{tools => providers}/git/util_test.go | 0 lib/providers/github/client.go | 278 +++++++++++++++ lib/providers/github/creds.go | 29 ++ lib/{tools/git => providers}/github/env.go | 26 -- .../git => providers}/github/env_test.go | 0 lib/providers/github/mocks/github.go | 334 ++++++++++++++++++ lib/providers/github/opts.go | 75 ++++ .../github/testdata/event.json | 0 lib/providers/go.mod | 66 ++++ lib/providers/go.sum | 193 ++++++++++ lib/schema/Earthfile | 2 +- lib/schema/go.mod | 4 +- lib/schema/go.sum | 42 +-- lib/secrets/.earthlyignore | 4 + lib/secrets/Earthfile | 39 ++ lib/secrets/LICENSE-APACHE | 201 +++++++++++ lib/secrets/LICENSE-MIT | 25 ++ lib/secrets/blueprint.cue | 1 + lib/{project => }/secrets/client.go | 2 +- lib/secrets/go.mod | 57 +++ lib/secrets/go.sum | 175 +++++++++ lib/{project => }/secrets/interface.go | 0 .../secrets/mocks/interface_mock.go | 3 +- lib/{project => }/secrets/providers.go | 0 lib/{project => }/secrets/providers/aws.go | 0 .../secrets/providers/aws_mock_test.go | 0 .../secrets/providers/aws_test.go | 0 lib/{project => }/secrets/providers/env.go | 0 .../secrets/providers/env_test.go | 0 lib/{project => }/secrets/providers/local.go | 0 .../secrets/providers/local_test.go | 0 lib/{project => }/secrets/secrets.go | 0 lib/tools/Earthfile | 2 +- lib/tools/git/github/client.go | 155 -------- lib/tools/go.mod | 39 +- lib/tools/go.sum | 92 +++-- 95 files changed, 2113 insertions(+), 884 deletions(-) delete mode 100644 cli/pkg/providers/kcl/client.go delete mode 100644 cli/pkg/providers/kcl/mocks/kcl.go delete mode 100644 lib/project/providers/github.go delete mode 100644 lib/project/utils/pointers.go create mode 100644 lib/providers/.earthlyignore create mode 100644 lib/providers/Earthfile create mode 100644 lib/providers/LICENSE-APACHE create mode 100644 lib/providers/LICENSE-MIT rename {cli/pkg => lib}/providers/aws/common.go (100%) rename {cli/pkg => lib}/providers/aws/ecr.go (93%) rename {cli/pkg => lib}/providers/aws/ecr_test.go (86%) rename {cli/pkg => lib}/providers/aws/mocks/ecr.go (100%) rename {cli/pkg => lib}/providers/aws/mocks/s3.go (100%) rename {cli/pkg => lib}/providers/aws/s3.go (100%) create mode 100644 lib/providers/blueprint.cue rename lib/{project/providers => providers/earthly}/earthly.go (94%) rename lib/{tools => providers}/git/branch.go (62%) rename lib/{project/providers => providers/git}/git.go (90%) rename lib/{tools => providers}/git/tag.go (67%) rename lib/{tools => providers}/git/util.go (100%) rename lib/{tools => providers}/git/util_test.go (100%) create mode 100644 lib/providers/github/client.go create mode 100644 lib/providers/github/creds.go rename lib/{tools/git => providers}/github/env.go (84%) rename lib/{tools/git => providers}/github/env_test.go (100%) create mode 100644 lib/providers/github/mocks/github.go create mode 100644 lib/providers/github/opts.go rename lib/{tools/git => providers}/github/testdata/event.json (100%) create mode 100644 lib/providers/go.mod create mode 100644 lib/providers/go.sum create mode 100644 lib/secrets/.earthlyignore create mode 100644 lib/secrets/Earthfile create mode 100644 lib/secrets/LICENSE-APACHE create mode 100644 lib/secrets/LICENSE-MIT create mode 100644 lib/secrets/blueprint.cue rename lib/{project => }/secrets/client.go (94%) create mode 100644 lib/secrets/go.mod create mode 100644 lib/secrets/go.sum rename lib/{project => }/secrets/interface.go (100%) rename lib/{project => }/secrets/mocks/interface_mock.go (97%) rename lib/{project => }/secrets/providers.go (100%) rename lib/{project => }/secrets/providers/aws.go (100%) rename lib/{project => }/secrets/providers/aws_mock_test.go (100%) rename lib/{project => }/secrets/providers/aws_test.go (100%) rename lib/{project => }/secrets/providers/env.go (100%) rename lib/{project => }/secrets/providers/env_test.go (100%) rename lib/{project => }/secrets/providers/local.go (100%) rename lib/{project => }/secrets/providers/local_test.go (100%) rename lib/{project => }/secrets/secrets.go (100%) delete mode 100644 lib/tools/git/github/client.go diff --git a/cli/Earthfile b/cli/Earthfile index 605a25fe..74de4452 100644 --- a/cli/Earthfile +++ b/cli/Earthfile @@ -1,7 +1,7 @@ VERSION 0.8 deps: - FROM golang:1.24.0-bookworm + FROM golang:1.24.2-bookworm WORKDIR /work @@ -13,7 +13,9 @@ deps: CACHE --persist --sharing shared /go COPY ../lib/project+src/src /lib/project + COPY ../lib/providers+src/src /lib/providers COPY ../lib/schema+src/src /lib/schema + COPY ../lib/secrets+src/src /lib/secrets COPY ../lib/tools+src/src /lib/tools COPY go.mod go.sum . diff --git a/cli/cmd/cmds/configure_satellite.go b/cli/cmd/cmds/configure_satellite.go index 37f19147..fce76b9b 100644 --- a/cli/cmd/cmds/configure_satellite.go +++ b/cli/cmd/cmds/configure_satellite.go @@ -7,8 +7,8 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly/satellite" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" - "github.com/input-output-hk/catalyst-forge/lib/tools/git" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/cli/cmd/cmds/secret.go b/cli/cmd/cmds/secret.go index 15231cdd..70a2aec9 100644 --- a/cli/cmd/cmds/secret.go +++ b/cli/cmd/cmds/secret.go @@ -7,8 +7,8 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/cli/pkg/utils" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" ) diff --git a/cli/cmd/main.go b/cli/cmd/main.go index a99ac0e6..9f2ac24d 100644 --- a/cli/cmd/main.go +++ b/cli/cmd/main.go @@ -14,8 +14,8 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" schema "github.com/input-output-hk/catalyst-forge/lib/schema" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" "github.com/posener/complete" "github.com/willabides/kongplete" diff --git a/cli/go.mod b/cli/go.mod index 2a87f2e9..e3a0cb10 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -1,31 +1,31 @@ module github.com/input-output-hk/catalyst-forge/cli -go 1.23.0 +go 1.24.2 require ( cuelang.org/go v0.12.0 github.com/alecthomas/kong v0.9.0 - github.com/aws/aws-sdk-go v1.55.5 - github.com/aws/aws-sdk-go-v2 v1.32.6 - github.com/aws/aws-sdk-go-v2/config v1.27.40 - github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 - github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 + github.com/aws/aws-sdk-go v1.55.7 + github.com/aws/aws-sdk-go-v2 v1.36.6 + github.com/aws/aws-sdk-go-v2/config v1.29.18 + github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1 github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.1.1 github.com/charmbracelet/lipgloss v0.13.0 github.com/charmbracelet/log v0.4.0 github.com/google/go-github/v66 v66.0.0 github.com/input-output-hk/catalyst-forge/lib/project v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/providers v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 - github.com/migueleliasweb/go-github-mock v1.0.1 github.com/posener/complete v1.2.3 github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a github.com/stretchr/testify v1.10.0 github.com/willabides/kongplete v0.4.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c gopkg.in/yaml.v3 v3.0.1 - kcl-lang.io/kpm v0.11.0 ) require ( @@ -48,22 +48,22 @@ require ( github.com/adrg/xdg v0.5.3 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230219212500-1f9a474cc2dc // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.38 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.31.4 // indirect - github.com/aws/smithy-go v1.22.1 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect + github.com/aws/smithy-go v1.22.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect @@ -131,7 +131,6 @@ require ( github.com/google/btree v1.0.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/go-github/v64 v64.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/s2a-go v0.1.7 // indirect @@ -261,6 +260,7 @@ require ( k8s.io/kubectl v0.32.0 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect kcl-lang.io/kcl-go v0.11.0 // indirect + kcl-lang.io/kpm v0.11.0 // indirect kcl-lang.io/lib v0.11.0 // indirect oras.land/oras-go v1.2.6 // indirect oras.land/oras-go/v2 v2.5.0 // indirect @@ -273,6 +273,10 @@ require ( replace github.com/input-output-hk/catalyst-forge/lib/project => ../lib/project +replace github.com/input-output-hk/catalyst-forge/lib/providers => ../lib/providers + replace github.com/input-output-hk/catalyst-forge/lib/schema => ../lib/schema +replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../lib/secrets + replace github.com/input-output-hk/catalyst-forge/lib/tools => ../lib/tools diff --git a/cli/go.sum b/cli/go.sum index 4339c60f..f6435af2 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -239,48 +239,48 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= -github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw= -github.com/aws/aws-sdk-go-v2/config v1.27.40 h1:sie4mPBGFOO+Z27+yHzvyN31G20h/bf2xb5mCbpLv2Q= -github.com/aws/aws-sdk-go-v2/config v1.27.40/go.mod h1:4KW7Aa5tNo+0VHnuLnnE1vPHtwMurlNZNS65IdcewHA= -github.com/aws/aws-sdk-go-v2/credentials v1.17.38 h1:iM90eRhCeZtlkzCNCG1JysOzJXGYf5rx80aD1lUgNDU= -github.com/aws/aws-sdk-go-v2/credentials v1.17.38/go.mod h1:TCVYPZeQuLaYNEkf/TVn6k5k/zdVZZ7xH9po548VNNg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 h1:mimdLQkIX1zr8GIPY1ZtALdBQGxcASiBd2MOp8m/dMc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16/go.mod h1:YHk6owoSwrIsok+cAH9PENCOGoH5PU2EllX4vLtSrsY= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 h1:R+5XKIJga2K9Dkj0/iQ6fD/MBGo02oxGGFTc512lK/Q= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7/go.mod h1:fDPQV/6ONOQOjvtKhtypIy1wcGLcKYtoK/lvZ9fyDGQ= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 h1:GckUnpm4EJOAio1c8o25a+b3lVfwVzC9gnSBqiiNmZM= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18/go.mod h1:Br6+bxfG33Dk3ynmkhsW2Z/t9D4+lRqdLDNCKi85w0U= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 h1:mx2ucgtv+MWzJesJY9Ig/8AFHgoE5FwLXwUVgW/FGdI= -github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 h1:EoPbZg+DGTRqKKhwk5uDviV9yvx65r1kyoNNC02ZH4Y= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4/go.mod h1:WyLS5qwXHtjKAONYZq/4ewdd+hcVsa3LBu77Ow5uj3k= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 h1:ck/Y8XWNR1gHa4BFkwE3oSu7XDJGwl+8TI7E/RB2EcQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.4/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 h1:4f2/JKYZHAZbQ7koBpZ012bKi32NHPY0m7TDuJgsbug= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.4 h1:uK6dUUdJtqutK1XO/tmNaQMJiPLCJY/eAeOOmqQ6ygY= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.4/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= -github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU= +github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= +github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I= +github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.37 h1:XTZZ0I3SZUHAtBLBU6395ad+VOblE0DwQP6MuaNeics= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.37/go.mod h1:Pi6ksbniAWVwu2S8pEzcYPyhUkAcLaufxN7PfAUQjBk= +github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0 h1:oyXvdONSO/VmFwEupTO+P5AFFghpNyM2MeYi7FARciM= +github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0/go.mod h1:uDcrAwhZkHtPAFst5Wx7WSAhMi8BvVegEkc0Kg16vUM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5 h1:M5/B8JUaCI8+9QD+u3S/f4YHpvqE9RpSkV3rf0Iks2w= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5/go.mod h1:Bktzci1bwdbpuLiu3AOksiNPMl/LLKmX1TWmqp2xbvs= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18 h1:OS2e0SKqsU2LiJPqL8u9x41tKc6MMEHrWjLVLn3oysg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18/go.mod h1:+Yrk+MDGzlNGxCXieljNeWpoZTCQUQVL+Jk9hGGJ8qM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1 h1:RkHXU9jP0DptGy7qKI8CBGsUJruWz0v5IgwBa2DwWcU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1/go.mod h1:3xAOf7tdKF+qbb+XpU+EPhNXAdun3Lu1RcDrj8KC24I= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 h1:HD6R8K10gPbN9CNqRDOs42QombXlYeLOr4KkIxe2lQs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8/go.mod h1:x66GdH8qjYTr6Kb4ik38Ewl6moLsg8igbceNsmxVxeA= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -559,8 +559,6 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v64 v64.0.0 h1:4G61sozmY3eiPAjjoOHponXDBONm+utovTKbyUb2Qdg= -github.com/google/go-github/v64 v64.0.0/go.mod h1:xB3vqMQNdHzilXBiO2I+M7iEFtHf+DP/omBOv6tQzVo= github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M= github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -735,8 +733,6 @@ github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= -github.com/migueleliasweb/go-github-mock v1.0.1 h1:amLEECVny28RCD1ElALUpQxrAimamznkg9rN2O7t934= -github.com/migueleliasweb/go-github-mock v1.0.1/go.mod h1:8PJ7MpMoIiCBBNpuNmvndHm0QicjsE+hjex1yMGmjYQ= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= diff --git a/cli/pkg/earthly/earthly.go b/cli/pkg/earthly/earthly.go index c29f10d8..52b69716 100644 --- a/cli/pkg/earthly/earthly.go +++ b/cli/pkg/earthly/earthly.go @@ -10,8 +10,8 @@ import ( "strings" "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" - secretstore "github.com/input-output-hk/catalyst-forge/lib/project/secrets" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + secretstore "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // EarthlyExecutorOption is an option for configuring an EarthlyExecutor. diff --git a/cli/pkg/earthly/earthly_test.go b/cli/pkg/earthly/earthly_test.go index 40ba97d3..4462b33a 100644 --- a/cli/pkg/earthly/earthly_test.go +++ b/cli/pkg/earthly/earthly_test.go @@ -6,9 +6,9 @@ import ( "testing" emocks "github.com/input-output-hk/catalyst-forge/cli/pkg/executor/mocks" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" - smocks "github.com/input-output-hk/catalyst-forge/lib/project/secrets/mocks" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + smocks "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" "github.com/stretchr/testify/assert" ) diff --git a/cli/pkg/earthly/project.go b/cli/pkg/earthly/project.go index 3c46f297..faff287b 100644 --- a/cli/pkg/earthly/project.go +++ b/cli/pkg/earthly/project.go @@ -10,9 +10,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" + "github.com/input-output-hk/catalyst-forge/lib/secrets" ) var ( diff --git a/cli/pkg/earthly/project_test.go b/cli/pkg/earthly/project_test.go index 3b71b032..c70fbfc7 100644 --- a/cli/pkg/earthly/project_test.go +++ b/cli/pkg/earthly/project_test.go @@ -10,9 +10,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/blueprint" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" - smocks "github.com/input-output-hk/catalyst-forge/lib/project/secrets/mocks" schema "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + smocks "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/cli/pkg/earthly/satellite/satellite.go b/cli/pkg/earthly/satellite/satellite.go index 574dff61..0ca55463 100644 --- a/cli/pkg/earthly/satellite/satellite.go +++ b/cli/pkg/earthly/satellite/satellite.go @@ -7,8 +7,8 @@ import ( "path/filepath" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/providers" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/earthly" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "gopkg.in/yaml.v3" @@ -17,7 +17,7 @@ import ( // EarthlySatellite is used to configure the local system to use a remote Earthly Satellite. type EarthlySatellite struct { ci bool - creds providers.EarthlyProviderCreds + creds earthly.EarthlyProviderCreds fs fs.Filesystem logger *slog.Logger path string @@ -104,7 +104,7 @@ func (s *EarthlySatellite) loadCredentials() error { return fmt.Errorf("no satellite credentials found") } - creds, err := providers.GetEarthlyProviderCreds( + creds, err := earthly.GetEarthlyProviderCreds( s.project.Blueprint.Global.Ci.Providers.Earthly.Satellite.Credentials, &s.secretStore, s.logger, diff --git a/cli/pkg/earthly/satellite/satellite_test.go b/cli/pkg/earthly/satellite/satellite_test.go index 9a0173fb..dceeb6f4 100644 --- a/cli/pkg/earthly/satellite/satellite_test.go +++ b/cli/pkg/earthly/satellite/satellite_test.go @@ -8,12 +8,12 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/internal/testutils" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" - smocks "github.com/input-output-hk/catalyst-forge/lib/project/secrets/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global/providers" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + smocks "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/stretchr/testify/require" diff --git a/cli/pkg/events/merge.go b/cli/pkg/events/merge.go index 60a1cf0e..35f6ca85 100644 --- a/cli/pkg/events/merge.go +++ b/cli/pkg/events/merge.go @@ -6,7 +6,7 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/tools/git" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" ) // MergeEvent fires when a merge occurs to the default branch. diff --git a/cli/pkg/events/tag_test.go b/cli/pkg/events/tag_test.go index 27ae6bd0..b201026a 100644 --- a/cli/pkg/events/tag_test.go +++ b/cli/pkg/events/tag_test.go @@ -5,8 +5,8 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" schema "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" "github.com/stretchr/testify/assert" ) diff --git a/cli/pkg/providers/kcl/client.go b/cli/pkg/providers/kcl/client.go deleted file mode 100644 index 9adef295..00000000 --- a/cli/pkg/providers/kcl/client.go +++ /dev/null @@ -1,73 +0,0 @@ -package kcl - -import ( - "bytes" - "fmt" - - kpm "kcl-lang.io/kpm/pkg/client" -) - -//go:generate go run github.com/matryer/moq@latest -skip-ensure -pkg mocks -out mocks/kcl.go . KCLClient - -type KCLClient interface { - Run(KCLModuleArgs) (string, error) - Log() string -} - -type DefaultKCLClient struct { - logOutput bytes.Buffer -} - -func (k DefaultKCLClient) Run(args KCLModuleArgs) (string, error) { - client, err := kpm.NewKpmClient() - if err != nil { - return "", fmt.Errorf("failed to create KPM client: %w", err) - } - - client.SetLogWriter(&k.logOutput) - - out, err := client.Run( - kpm.WithRunSourceUrl(fmt.Sprintf("oci://%s?tag=%s", args.Module, args.Version)), - kpm.WithArguments(args.Serialize()), - ) - - if err != nil { - return "", fmt.Errorf("failed to run KCL module: %w", err) - } - - return out.GetRawYamlResult(), nil -} - -func (k DefaultKCLClient) Log() string { - return k.logOutput.String() -} - -// KCLModuleArgs contains the arguments to pass to the KCL module. -type KCLModuleArgs struct { - // InstanceName is the name to use for the deployment instance. - InstanceName string - - // Module is the name of the OCI module to deploy. - Module string - - // Namespace is the namespace to deploy the module to. - Namespace string - - // Values contains the values to pass to the module. - Values string - - // Version is the version of the module to deploy. - Version string -} - -// Serialize serializes the KCLModuleArgs to a list of arguments. -func (k *KCLModuleArgs) Serialize() []string { - return []string{ - "-D", - fmt.Sprintf("name=%s", k.InstanceName), - "-D", - fmt.Sprintf("namespace=%s", k.Namespace), - "-D", - fmt.Sprintf("values=%s", k.Values), - } -} diff --git a/cli/pkg/providers/kcl/mocks/kcl.go b/cli/pkg/providers/kcl/mocks/kcl.go deleted file mode 100644 index f65a1879..00000000 --- a/cli/pkg/providers/kcl/mocks/kcl.go +++ /dev/null @@ -1,108 +0,0 @@ -// Code generated by moq; DO NOT EDIT. -// github.com/matryer/moq - -package mocks - -import ( - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/kcl" - "sync" -) - -// KCLClientMock is a mock implementation of kcl.KCLClient. -// -// func TestSomethingThatUsesKCLClient(t *testing.T) { -// -// // make and configure a mocked kcl.KCLClient -// mockedKCLClient := &KCLClientMock{ -// LogFunc: func() string { -// panic("mock out the Log method") -// }, -// RunFunc: func(kCLModuleArgs kcl.KCLModuleArgs) (string, error) { -// panic("mock out the Run method") -// }, -// } -// -// // use mockedKCLClient in code that requires kcl.KCLClient -// // and then make assertions. -// -// } -type KCLClientMock struct { - // LogFunc mocks the Log method. - LogFunc func() string - - // RunFunc mocks the Run method. - RunFunc func(kCLModuleArgs kcl.KCLModuleArgs) (string, error) - - // calls tracks calls to the methods. - calls struct { - // Log holds details about calls to the Log method. - Log []struct { - } - // Run holds details about calls to the Run method. - Run []struct { - // KCLModuleArgs is the kCLModuleArgs argument value. - KCLModuleArgs kcl.KCLModuleArgs - } - } - lockLog sync.RWMutex - lockRun sync.RWMutex -} - -// Log calls LogFunc. -func (mock *KCLClientMock) Log() string { - if mock.LogFunc == nil { - panic("KCLClientMock.LogFunc: method is nil but KCLClient.Log was just called") - } - callInfo := struct { - }{} - mock.lockLog.Lock() - mock.calls.Log = append(mock.calls.Log, callInfo) - mock.lockLog.Unlock() - return mock.LogFunc() -} - -// LogCalls gets all the calls that were made to Log. -// Check the length with: -// -// len(mockedKCLClient.LogCalls()) -func (mock *KCLClientMock) LogCalls() []struct { -} { - var calls []struct { - } - mock.lockLog.RLock() - calls = mock.calls.Log - mock.lockLog.RUnlock() - return calls -} - -// Run calls RunFunc. -func (mock *KCLClientMock) Run(kCLModuleArgs kcl.KCLModuleArgs) (string, error) { - if mock.RunFunc == nil { - panic("KCLClientMock.RunFunc: method is nil but KCLClient.Run was just called") - } - callInfo := struct { - KCLModuleArgs kcl.KCLModuleArgs - }{ - KCLModuleArgs: kCLModuleArgs, - } - mock.lockRun.Lock() - mock.calls.Run = append(mock.calls.Run, callInfo) - mock.lockRun.Unlock() - return mock.RunFunc(kCLModuleArgs) -} - -// RunCalls gets all the calls that were made to Run. -// Check the length with: -// -// len(mockedKCLClient.RunCalls()) -func (mock *KCLClientMock) RunCalls() []struct { - KCLModuleArgs kcl.KCLModuleArgs -} { - var calls []struct { - KCLModuleArgs kcl.KCLModuleArgs - } - mock.lockRun.RLock() - calls = mock.calls.Run - mock.lockRun.RUnlock() - return calls -} diff --git a/cli/pkg/release/providers/common.go b/cli/pkg/release/providers/common.go index 3664fca7..bc20d354 100644 --- a/cli/pkg/release/providers/common.go +++ b/cli/pkg/release/providers/common.go @@ -6,8 +6,8 @@ import ( "regexp" "strings" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" s "github.com/input-output-hk/catalyst-forge/lib/schema" ) @@ -27,7 +27,7 @@ func createECRRepoIfNotExists(client aws.ECRClient, p *project.Project, registry if !exists { logger.Info("ECR repository does not exist, creating", "name", name) - if err := client.CreateECRRepository(p, name); err != nil { + if err := client.CreateECRRepository(name, p.Blueprint.Global.Repo.Name, p.Path); err != nil { return fmt.Errorf("failed to create ECR repository: %w", err) } } diff --git a/cli/pkg/release/providers/common_test.go b/cli/pkg/release/providers/common_test.go index c9fc3e02..4ffabb55 100644 --- a/cli/pkg/release/providers/common_test.go +++ b/cli/pkg/release/providers/common_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/aws/aws-sdk-go-v2/service/ecr" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" diff --git a/cli/pkg/release/providers/cue.go b/cli/pkg/release/providers/cue.go index fb171086..3477d7bc 100644 --- a/cli/pkg/release/providers/cue.go +++ b/cli/pkg/release/providers/cue.go @@ -11,9 +11,9 @@ import ( "cuelang.org/go/cue/cuecontext" "github.com/input-output-hk/catalyst-forge/cli/pkg/events" "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" "github.com/input-output-hk/catalyst-forge/lib/schema" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" lc "github.com/input-output-hk/catalyst-forge/lib/tools/cue" diff --git a/cli/pkg/release/providers/cue_test.go b/cli/pkg/release/providers/cue_test.go index 61620a2d..0bf198cb 100644 --- a/cli/pkg/release/providers/cue_test.go +++ b/cli/pkg/release/providers/cue_test.go @@ -9,9 +9,9 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ecr" exmocks "github.com/input-output-hk/catalyst-forge/cli/pkg/executor/mocks" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" spr "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global/providers" diff --git a/cli/pkg/release/providers/docker.go b/cli/pkg/release/providers/docker.go index bc29a9da..f2205ad2 100644 --- a/cli/pkg/release/providers/docker.go +++ b/cli/pkg/release/providers/docker.go @@ -8,9 +8,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" "github.com/input-output-hk/catalyst-forge/cli/pkg/events" "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" ) diff --git a/cli/pkg/release/providers/docker_test.go b/cli/pkg/release/providers/docker_test.go index ffb0a1d8..d116cb07 100644 --- a/cli/pkg/release/providers/docker_test.go +++ b/cli/pkg/release/providers/docker_test.go @@ -8,9 +8,9 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ecr" exmocks "github.com/input-output-hk/catalyst-forge/cli/pkg/executor/mocks" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 16af5835..f40e248b 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -10,15 +10,14 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" "github.com/input-output-hk/catalyst-forge/cli/pkg/events" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/providers" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" + "github.com/input-output-hk/catalyst-forge/lib/providers/github" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" - "github.com/input-output-hk/catalyst-forge/lib/tools/git" - "github.com/input-output-hk/catalyst-forge/lib/tools/git/github" ) const ( @@ -43,6 +42,7 @@ type DocsReleaser struct { config DocsReleaserConfig force bool fs fs.Filesystem + ghClient github.GithubClient handler events.EventHandler logger *slog.Logger project *project.Project @@ -100,17 +100,8 @@ func (r *DocsReleaser) Release() error { } if github.InCI() { - client, err := providers.NewGithubClient(r.project, r.logger) - if err != nil { - return fmt.Errorf("failed to create github client: %w", err) - } - - owner := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[0] - repo := strings.Split(r.project.Blueprint.Global.Repo.Name, "/")[1] - gc := github.NewGithubClient(owner, repo, client, r.logger) url := r.project.Blueprint.Global.Ci.Release.Docs.Url - - if err := r.postComment(gc, url, projectName); err != nil { + if err := r.postComment(url, projectName); err != nil { return fmt.Errorf("failed to post comment: %w", err) } @@ -120,7 +111,7 @@ func (r *DocsReleaser) Release() error { } if isDefault { - if err := r.cleanupBranches(gc, docsConfig.Bucket, filepath.Join(s3Path, "branches")); err != nil { + if err := r.cleanupBranches(docsConfig.Bucket, filepath.Join(s3Path, "branches")); err != nil { return fmt.Errorf("failed to cleanup branches: %w", err) } } @@ -131,8 +122,8 @@ func (r *DocsReleaser) Release() error { } // cleanupBranches deletes branches from S3 that are no longer present in GitHub. -func (r *DocsReleaser) cleanupBranches(client github.GithubClient, bucket, path string) error { - branches, err := client.ListBranches() +func (r *DocsReleaser) cleanupBranches(bucket, path string) error { + branches, err := r.ghClient.ListBranches() if err != nil { return fmt.Errorf("failed to list GitHub branches: %w", err) } @@ -194,16 +185,15 @@ func (r *DocsReleaser) isDefaultBranch() (bool, error) { } // postComment posts a comment to the PR. -func (r *DocsReleaser) postComment(client github.GithubClient, baseURL, name string) error { - env := github.NewGithubEnv(r.logger) - if env.IsPR() { - pr := env.GetPRNumber() +func (r *DocsReleaser) postComment(baseURL, name string) error { + if r.ghClient.Env().IsPR() { + pr := r.ghClient.Env().GetPRNumber() if pr == 0 { r.logger.Warn("No PR number found, skipping comment") return nil } - comments, err := client.ListPullRequestComments(pr) + comments, err := r.ghClient.ListPullRequestComments(pr) if err != nil { return fmt.Errorf("failed to list comments: %w", err) } @@ -231,7 +221,7 @@ func (r *DocsReleaser) postComment(client github.GithubClient, baseURL, name str } body := fmt.Sprintf(bodyTemplate, docsCommentPrefix, docURL) - if err := client.PostPullRequestComment(pr, body); err != nil { + if err := r.ghClient.PostPullRequestComment(pr, body); err != nil { return fmt.Errorf("failed to post comment to PR: %w", err) } } else { @@ -299,12 +289,25 @@ func NewDocsReleaser( return nil, fmt.Errorf("failed to create S3 client: %w", err) } + owner := strings.Split(project.Blueprint.Global.Repo.Name, "/")[0] + repo := strings.Split(project.Blueprint.Global.Repo.Name, "/")[1] + ghClient, err := github.NewDefaultGithubClient( + owner, + repo, + github.WithCredsOrEnv(project.Blueprint.Global.Ci.Providers.Github.Credentials), + github.WithLogger(ctx.Logger), + ) + if err != nil { + return nil, fmt.Errorf("failed to create github client: %w", err) + } + handler := events.NewDefaultEventHandler(ctx.Logger) runner := earthly.NewDefaultProjectRunner(ctx, &project) return &DocsReleaser{ config: config, force: force, fs: fs, + ghClient: ghClient, handler: &handler, logger: ctx.Logger, project: &project, diff --git a/cli/pkg/release/providers/docs_test.go b/cli/pkg/release/providers/docs_test.go index fd78c215..a3697b34 100644 --- a/cli/pkg/release/providers/docs_test.go +++ b/cli/pkg/release/providers/docs_test.go @@ -15,9 +15,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly" earthlyMocks "github.com/input-output-hk/catalyst-forge/cli/pkg/earthly/mocks" eventsMocks "github.com/input-output-hk/catalyst-forge/cli/pkg/events/mocks" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" - awsMocks "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" + awsMocks "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" diff --git a/cli/pkg/release/providers/github.go b/cli/pkg/release/providers/github.go index 0a6b1014..bc13eefc 100644 --- a/cli/pkg/release/providers/github.go +++ b/cli/pkg/release/providers/github.go @@ -1,7 +1,7 @@ package providers import ( - "context" + "errors" "fmt" "log/slog" "path/filepath" @@ -12,7 +12,7 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/events" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/providers" + gh "github.com/input-output-hk/catalyst-forge/lib/providers/github" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/archive" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" @@ -25,7 +25,7 @@ type GithubReleaserConfig struct { } type GithubReleaser struct { - client *github.Client + client gh.GithubClient config GithubReleaserConfig force bool fs fs.Filesystem @@ -71,15 +71,10 @@ func (r *GithubReleaser) Release() error { assets = append(assets, filename) } - parts := strings.Split(r.project.Blueprint.Global.Repo.Name, "/") - owner, repo := parts[0], parts[1] - - ctx := context.Background() - - release, resp, err := r.client.Repositories.GetReleaseByTag(ctx, owner, repo, r.project.Tag.Full) - if resp.StatusCode == 404 { + release, err := r.client.GetReleaseByTag(r.project.Tag.Full) + if errors.Is(err, gh.ErrReleaseNotFound) { r.logger.Info("Creating release", "name", r.config.Name) - release, _, err = r.client.Repositories.CreateRelease(ctx, owner, repo, &github.RepositoryRelease{ + release, err = r.client.CreateRelease(&github.RepositoryRelease{ Name: &r.config.Name, TagName: &r.project.Tag.Full, Draft: github.Bool(false), @@ -101,28 +96,9 @@ func (r *GithubReleaser) Release() error { } r.logger.Info("Uploading asset", "asset", asset) - f, err := r.fs.Open(filepath.Join(r.workdir, asset)) - if err != nil { - return fmt.Errorf("failed to open asset: %w", err) - } - - stat, err := f.Stat() - if err != nil { - return fmt.Errorf("failed to stat asset: %w", err) - } - - url := fmt.Sprintf("repos/%s/%s/releases/%d/assets?name=%s", owner, repo, *release.ID, asset) - req, err := r.client.NewUploadRequest(url, f, stat.Size(), "application/gzip") - if err != nil { - return fmt.Errorf("failed to create upload request: %w", err) - } - - _, err = r.client.Do(ctx, req, nil) - if err != nil { + if err := r.client.UploadReleaseAsset(*release.ID, filepath.Join(r.workdir, asset)); err != nil { return fmt.Errorf("failed to upload asset: %w", err) } - - f.Close() } return nil @@ -205,7 +181,14 @@ func NewGithubReleaser( return nil, fmt.Errorf("failed to create temporary directory: %w", err) } - client, err := providers.NewGithubClient(&project, ctx.Logger) + owner := strings.Split(project.Blueprint.Global.Repo.Name, "/")[0] + repo := strings.Split(project.Blueprint.Global.Repo.Name, "/")[1] + client, err := gh.NewDefaultGithubClient( + owner, + repo, + gh.WithCredsOrEnv(project.Blueprint.Global.Ci.Providers.Github.Credentials), + gh.WithLogger(ctx.Logger), + ) if err != nil { return nil, fmt.Errorf("failed to create github client: %w", err) } diff --git a/cli/pkg/release/providers/github_test.go b/cli/pkg/release/providers/github_test.go index 6be46f71..232cc4a4 100644 --- a/cli/pkg/release/providers/github_test.go +++ b/cli/pkg/release/providers/github_test.go @@ -6,19 +6,19 @@ import ( "compress/gzip" "fmt" "io" - "net/http" "path/filepath" "testing" "github.com/google/go-github/v66/github" "github.com/input-output-hk/catalyst-forge/lib/project/project" + gh "github.com/input-output-hk/catalyst-forge/lib/providers/github" + gm "github.com/input-output-hk/catalyst-forge/lib/providers/github/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" - "github.com/migueleliasweb/go-github-mock/src/mock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -105,8 +105,7 @@ func TestGithubReleaserRelease(t *testing.T) { assert.True(t, created) - url := fmt.Sprintf("/repos/owner/repo/releases/123456/assets?name=%s", filename) - data, ok := uploads[url] + data, ok := uploads[filename] assert.True(t, ok) files := make(map[string]string) @@ -161,8 +160,7 @@ func TestGithubReleaserRelease(t *testing.T) { require.NoError(t, err) assert.True(t, exists) - url := fmt.Sprintf("/repos/owner/repo/releases/123456/assets?name=%s", filename) - data, ok := uploads[url] + data, ok := uploads[filename] assert.True(t, ok) files := make(map[string]string) @@ -348,67 +346,36 @@ func TestGithubReleaserRelease(t *testing.T) { var releaseCreated bool uploads := make(map[string][]byte) - client := github.NewClient( - mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposReleasesTagsByOwnerByRepoByTag, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, _ := io.ReadAll(r.Body) - uploads[r.URL.String()] = body - - if tt.ghRelease.ID == nil { - mock.WriteError( - w, - http.StatusNotFound, - "release not found", - ) - return - } - - w.Write(mock.MustMarshal(tt.ghRelease)) - }), - ), - mock.WithRequestMatchHandler( - mock.PostReposReleasesByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if tt.createFail { - mock.WriteError( - w, - http.StatusInternalServerError, - "failed to create release", - ) - return - } - - releaseCreated = true - w.Write(mock.MustMarshal(github.RepositoryRelease{ - ID: github.Int64(123456), - })) - }), - ), - mock.WithRequestMatchHandler( - mock.PostReposReleasesAssetsByOwnerByRepoByReleaseId, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, _ := io.ReadAll(r.Body) - uploads[r.URL.String()] = body - - if tt.uploadFail { - mock.WriteError( - w, - http.StatusInternalServerError, - "failed to upload asset", - ) - return - } - - w.Write(mock.MustMarshal(github.ReleaseAsset{})) - }), - ), - ), - ) + client := gm.GithubClientMock{ + GetReleaseByTagFunc: func(tag string) (*github.RepositoryRelease, error) { + if tt.ghRelease.ID == nil { + return nil, gh.ErrReleaseNotFound + } + return &tt.ghRelease, nil + }, + CreateReleaseFunc: func(opts *github.RepositoryRelease) (*github.RepositoryRelease, error) { + if tt.createFail { + return nil, fmt.Errorf("failed to create release") + } + releaseCreated = true + return &github.RepositoryRelease{ + ID: github.Int64(123456), + }, nil + }, + UploadReleaseAssetFunc: func(releaseID int64, path string) error { + if tt.uploadFail { + return fmt.Errorf("failed to upload asset") + } + assetName := filepath.Base(path) + assetContent, err := fs.ReadFile(path) + require.NoError(t, err) + uploads[assetName] = assetContent + return nil + }, + } releaser := GithubReleaser{ - client: client, + client: &client, config: tt.config, force: tt.force, fs: fs, diff --git a/cli/pkg/release/providers/kcl.go b/cli/pkg/release/providers/kcl.go index b87e5f8b..791c9b9e 100644 --- a/cli/pkg/release/providers/kcl.go +++ b/cli/pkg/release/providers/kcl.go @@ -6,9 +6,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/events" "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" ) diff --git a/cli/pkg/release/providers/kcl_test.go b/cli/pkg/release/providers/kcl_test.go index 37d27dc4..80853211 100644 --- a/cli/pkg/release/providers/kcl_test.go +++ b/cli/pkg/release/providers/kcl_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/aws/aws-sdk-go-v2/service/ecr" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" spr "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global/providers" diff --git a/cli/pkg/run/context.go b/cli/pkg/run/context.go index c763e2e0..19cd6d32 100644 --- a/cli/pkg/run/context.go +++ b/cli/pkg/run/context.go @@ -6,7 +6,7 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/cli/tui/ci/app.go b/cli/tui/ci/app.go index 486d85c3..a5e61a9d 100644 --- a/cli/tui/ci/app.go +++ b/cli/tui/ci/app.go @@ -15,7 +15,7 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/cli/tui" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/tools/git" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/cli/tui/ci/ci.go b/cli/tui/ci/ci.go index 2dbeb746..59adbb13 100644 --- a/cli/tui/ci/ci.go +++ b/cli/tui/ci/ci.go @@ -16,7 +16,7 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/cli/pkg/scan" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/lib/project/Earthfile b/lib/project/Earthfile index 7be8fcdc..4e7aa497 100644 --- a/lib/project/Earthfile +++ b/lib/project/Earthfile @@ -1,7 +1,7 @@ VERSION 0.8 deps: - FROM golang:1.24.0-bookworm + FROM golang:1.24.2-bookworm WORKDIR /work @@ -10,7 +10,9 @@ deps: ENV GOMODCACHE=/go/modcache CACHE --persist --sharing shared /go + COPY ../providers+src/src /providers COPY ../schema+src/src /schema + COPY ../secrets+src/src /secrets COPY ../tools+src/src /tools COPY go.mod go.sum . diff --git a/lib/project/deployment/deployer/deployer.go b/lib/project/deployment/deployer/deployer.go index 230ed51c..69b0ac34 100644 --- a/lib/project/deployment/deployer/deployer.go +++ b/lib/project/deployment/deployer/deployer.go @@ -10,9 +10,9 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/deployment/generator" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/providers" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" @@ -332,7 +332,7 @@ func (d *Deployer) clone(url, ref string, fs fs.Filesystem) (repo.GitRepo, error repo.WithFS(fs), } - creds, err := providers.GetGitProviderCreds(&d.cfg.Git.Creds, &d.ss, d.logger) + creds, err := git.GetGitProviderCreds(&d.cfg.Git.Creds, &d.ss, d.logger) if err != nil { d.logger.Warn("could not get git provider credentials, not using any authentication", "error", err) } else { diff --git a/lib/project/deployment/module.go b/lib/project/deployment/module.go index 2c230563..f77d03a2 100644 --- a/lib/project/deployment/module.go +++ b/lib/project/deployment/module.go @@ -8,8 +8,8 @@ import ( "cuelang.org/go/cue/cuecontext" "cuelang.org/go/cue/format" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) diff --git a/lib/project/deployment/module_test.go b/lib/project/deployment/module_test.go index 4628814a..76a7ca0c 100644 --- a/lib/project/deployment/module_test.go +++ b/lib/project/deployment/module_test.go @@ -5,9 +5,9 @@ import ( "testing" "cuelang.org/go/cue/cuecontext" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" - sm "github.com/input-output-hk/catalyst-forge/lib/project/secrets/mocks" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + sm "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" diff --git a/lib/project/go.mod b/lib/project/go.mod index ea6a65ba..e4b95a27 100644 --- a/lib/project/go.mod +++ b/lib/project/go.mod @@ -3,14 +3,12 @@ module github.com/input-output-hk/catalyst-forge/lib/project require ( cuelang.org/go v0.12.0 github.com/BurntSushi/toml v1.4.0 - github.com/Masterminds/semver/v3 v3.3.1 - github.com/aws/aws-sdk-go v1.55.5 - github.com/aws/aws-sdk-go-v2/config v1.27.40 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 github.com/google/go-github/v66 v66.0.0 + github.com/input-output-hk/catalyst-forge/lib/providers v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 github.com/stretchr/testify v1.10.0 helm.sh/helm/v3 v3.17.0 @@ -28,6 +26,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect @@ -35,18 +34,21 @@ require ( github.com/adrg/xdg v0.5.3 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230219212500-1f9a474cc2dc // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.31.0 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.38 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.31.4 // indirect - github.com/aws/smithy-go v1.21.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.6 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.18 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect + github.com/aws/smithy-go v1.22.4 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -241,8 +243,12 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) +replace github.com/input-output-hk/catalyst-forge/lib/providers => ../providers + replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema +replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../secrets + replace github.com/input-output-hk/catalyst-forge/lib/tools => ../tools -go 1.23.0 +go 1.24.2 diff --git a/lib/project/go.sum b/lib/project/go.sum index a5ef652d..266c3df0 100644 --- a/lib/project/go.sum +++ b/lib/project/go.sum @@ -233,36 +233,36 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/config v1.27.40 h1:sie4mPBGFOO+Z27+yHzvyN31G20h/bf2xb5mCbpLv2Q= -github.com/aws/aws-sdk-go-v2/config v1.27.40/go.mod h1:4KW7Aa5tNo+0VHnuLnnE1vPHtwMurlNZNS65IdcewHA= -github.com/aws/aws-sdk-go-v2/credentials v1.17.38 h1:iM90eRhCeZtlkzCNCG1JysOzJXGYf5rx80aD1lUgNDU= -github.com/aws/aws-sdk-go-v2/credentials v1.17.38/go.mod h1:TCVYPZeQuLaYNEkf/TVn6k5k/zdVZZ7xH9po548VNNg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 h1:EoPbZg+DGTRqKKhwk5uDviV9yvx65r1kyoNNC02ZH4Y= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4/go.mod h1:WyLS5qwXHtjKAONYZq/4ewdd+hcVsa3LBu77Ow5uj3k= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 h1:ck/Y8XWNR1gHa4BFkwE3oSu7XDJGwl+8TI7E/RB2EcQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.4/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 h1:4f2/JKYZHAZbQ7koBpZ012bKi32NHPY0m7TDuJgsbug= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.4 h1:uK6dUUdJtqutK1XO/tmNaQMJiPLCJY/eAeOOmqQ6ygY= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.4/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU= +github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I= +github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 h1:HD6R8K10gPbN9CNqRDOs42QombXlYeLOr4KkIxe2lQs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8/go.mod h1:x66GdH8qjYTr6Kb4ik38Ewl6moLsg8igbceNsmxVxeA= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/lib/project/project/loader.go b/lib/project/project/loader.go index fec8c6d2..feb6c608 100644 --- a/lib/project/project/loader.go +++ b/lib/project/project/loader.go @@ -11,12 +11,12 @@ import ( "cuelang.org/go/cue/cuecontext" "github.com/input-output-hk/catalyst-forge/lib/project/blueprint" "github.com/input-output-hk/catalyst-forge/lib/project/injector" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/earthly" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" - "github.com/input-output-hk/catalyst-forge/lib/tools/git" r "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/lib/project/project/project.go b/lib/project/project/project.go index 6e796ff9..234ce8ec 100644 --- a/lib/project/project/project.go +++ b/lib/project/project/project.go @@ -8,8 +8,8 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/blueprint" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/earthly" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) diff --git a/lib/project/project/runtime.go b/lib/project/project/runtime.go index c91c90c1..75f95bb1 100644 --- a/lib/project/project/runtime.go +++ b/lib/project/project/runtime.go @@ -6,11 +6,11 @@ import ( "cuelang.org/go/cue" "github.com/google/go-github/v66/github" + gh "github.com/input-output-hk/catalyst-forge/lib/providers/github" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" - gh "github.com/input-output-hk/catalyst-forge/lib/tools/git/github" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) @@ -96,11 +96,15 @@ func (g *GitRuntime) Load(project *Project) map[string]cue.Value { // getCommitHash returns the commit hash of the HEAD commit. func (g *GitRuntime) getCommitHash(repo *repo.GitRepo) (string, error) { - env := gh.NewCustomGithubEnv(g.fs, g.logger) - if env.HasEvent() { - if env.GetEventType() == "pull_request" { + gc, err := gh.NewDefaultGithubClient("", "", gh.WithFs(g.fs), gh.WithLogger(g.logger)) + if err != nil { + return "", fmt.Errorf("failed to create github client: %w", err) + } + + if gc.Env().HasEvent() { + if gc.Env().GetEventType() == "pull_request" { g.logger.Debug("Found GitHub pull request event") - event, err := env.GetEventPayload() + event, err := gc.Env().GetEventPayload() if err != nil { return "", fmt.Errorf("failed to get event payload: %w", err) } @@ -115,9 +119,9 @@ func (g *GitRuntime) getCommitHash(repo *repo.GitRepo) (string, error) { } return *pr.PullRequest.Head.SHA, nil - } else if env.GetEventType() == "push" { - g.logger.Debug("Found GitHub push event") - event, err := env.GetEventPayload() + } else if gc.Env().GetEventType() == "push" { + g.logger.Debug("xFound GitHub push event") + event, err := gc.Env().GetEventPayload() if err != nil { return "", fmt.Errorf("failed to get event payload: %w", err) } diff --git a/lib/project/providers/github.go b/lib/project/providers/github.go deleted file mode 100644 index b120f68c..00000000 --- a/lib/project/providers/github.go +++ /dev/null @@ -1,59 +0,0 @@ -package providers - -import ( - "fmt" - "log/slog" - "os" - - "github.com/google/go-github/v66/github" - "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" -) - -// GithubProviderCreds is the struct that holds the credentials for the Github provider -type GithubProviderCreds struct { - Token string -} - -// GetGithubProviderCreds loads the Github provider credentials from the project. -func GetGithubProviderCreds(p *project.Project, logger *slog.Logger) (GithubProviderCreds, error) { - secret := p.Blueprint.Global.Ci.Providers.Github.Credentials - if secret == nil { - return GithubProviderCreds{}, fmt.Errorf("project does not have a Github provider configured") - } - - m, err := secrets.GetSecretMap(secret, &p.SecretStore, logger) - if err != nil { - return GithubProviderCreds{}, fmt.Errorf("could not get secret: %w", err) - } - - creds, ok := m["token"] - if !ok { - return GithubProviderCreds{}, fmt.Errorf("github provider token is missing in secret") - } - - return GithubProviderCreds{Token: creds}, nil -} - -// NewGithubClient returns a new Github client. -// If a GITHUB_TOKEN environment variable is set, it will use that token. -// Otherwise, it will use the provider secret. -// If neither are set, it will create an anonymous client. -func NewGithubClient(p *project.Project, logger *slog.Logger) (*github.Client, error) { - token, exists := os.LookupEnv("GITHUB_TOKEN") - if exists { - logger.Info("Creating Github client with environment token") - return github.NewClient(nil).WithAuthToken(token), nil - } else if p.Blueprint.Global.Ci.Providers.Github.Credentials != nil { - logger.Info("Creating Github client with provider secret") - creds, err := GetGithubProviderCreds(p, logger) - if err != nil { - logger.Error("Failed to get Github provider credentials", "error", err) - } - - return github.NewClient(nil).WithAuthToken(creds.Token), nil - } - - logger.Info("Creating new anonymous Github client") - return github.NewClient(nil), nil -} diff --git a/lib/project/utils/pointers.go b/lib/project/utils/pointers.go deleted file mode 100644 index d0b60993..00000000 --- a/lib/project/utils/pointers.go +++ /dev/null @@ -1,16 +0,0 @@ -package utils - -// IntPtr returns a pointer to an integer. -func IntPtr(i int) *int { - return &i -} - -// StringPtr returns a pointer to a string. -func StringPtr(s string) *string { - return &s -} - -// BoolPtr returns a pointer to a boolean. -func BoolPtr(b bool) *bool { - return &b -} diff --git a/lib/project/utils/test/secrets.go b/lib/project/utils/test/secrets.go index fab35ace..296db8de 100644 --- a/lib/project/utils/test/secrets.go +++ b/lib/project/utils/test/secrets.go @@ -4,8 +4,8 @@ import ( "encoding/json" "log/slog" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" - sm "github.com/input-output-hk/catalyst-forge/lib/project/secrets/mocks" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + sm "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" ) func NewMockSecretStore(result map[string]string) secrets.SecretStore { diff --git a/lib/providers/.earthlyignore b/lib/providers/.earthlyignore new file mode 100644 index 00000000..3d720b45 --- /dev/null +++ b/lib/providers/.earthlyignore @@ -0,0 +1,4 @@ +Earthfile +README.md +LICENSE-* +blueprint.cue \ No newline at end of file diff --git a/lib/providers/Earthfile b/lib/providers/Earthfile new file mode 100644 index 00000000..db81f18a --- /dev/null +++ b/lib/providers/Earthfile @@ -0,0 +1,40 @@ +VERSION 0.8 + +deps: + FROM golang:1.24.2-bookworm + + WORKDIR /work + + RUN mkdir -p /go/cache && mkdir -p /go/modcache + ENV GOCACHE=/go/cache + ENV GOMODCACHE=/go/modcache + CACHE --persist --sharing shared /go + + COPY ../schema+src/src /schema + COPY ../secrets+src/src /secrets + COPY ../tools+src/src /tools + + COPY go.mod go.sum . + RUN go mod download + +src: + FROM +deps + + CACHE --persist --sharing shared /go + + COPY . . + + RUN go generate ./... + + SAVE ARTIFACT . src + +check: + FROM +src + + RUN gofmt -l . | grep . && exit 1 || exit 0 + RUN go vet ./... + +test: + FROM +src + + RUN go test ./... \ No newline at end of file diff --git a/lib/providers/LICENSE-APACHE b/lib/providers/LICENSE-APACHE new file mode 100644 index 00000000..a55761ab --- /dev/null +++ b/lib/providers/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2023 Input Output (IOG). + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/lib/providers/LICENSE-MIT b/lib/providers/LICENSE-MIT new file mode 100644 index 00000000..ac4df9c0 --- /dev/null +++ b/lib/providers/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2024 Input Output (IOG). + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/cli/pkg/providers/aws/common.go b/lib/providers/aws/common.go similarity index 100% rename from cli/pkg/providers/aws/common.go rename to lib/providers/aws/common.go diff --git a/cli/pkg/providers/aws/ecr.go b/lib/providers/aws/ecr.go similarity index 93% rename from cli/pkg/providers/aws/ecr.go rename to lib/providers/aws/ecr.go index 49820670..783d32b9 100644 --- a/cli/pkg/providers/aws/ecr.go +++ b/lib/providers/aws/ecr.go @@ -10,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ecr" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/aws-sdk-go/aws" - "github.com/input-output-hk/catalyst-forge/lib/project/project" ) //go:generate go run github.com/matryer/moq@latest -skip-ensure --pkg mocks -out mocks/ecr.go . AWSECRClient @@ -30,7 +29,7 @@ type ECRClient struct { // CreateECRRepository creates a new ECR repository. // By default, the repository is immutable and has image scanning enabled. // The repository is also tagged with metadata about the given project. -func (c *ECRClient) CreateECRRepository(project *project.Project, name string) error { +func (c *ECRClient) CreateECRRepository(name string, gitRepoName, gitRepoPath string) error { input := &ecr.CreateRepositoryInput{ RepositoryName: aws.String(name), ImageTagMutability: types.ImageTagMutabilityImmutable, @@ -47,11 +46,11 @@ func (c *ECRClient) CreateECRRepository(project *project.Project, name string) e }, { Key: aws.String("Repo"), - Value: aws.String(project.Blueprint.Global.Repo.Name), + Value: aws.String(gitRepoName), }, { Key: aws.String("RepoPath"), - Value: aws.String(project.Path), + Value: aws.String(gitRepoPath), }, }, } diff --git a/cli/pkg/providers/aws/ecr_test.go b/lib/providers/aws/ecr_test.go similarity index 86% rename from cli/pkg/providers/aws/ecr_test.go rename to lib/providers/aws/ecr_test.go index 6332ec70..f6c31385 100644 --- a/cli/pkg/providers/aws/ecr_test.go +++ b/lib/providers/aws/ecr_test.go @@ -8,39 +8,23 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ecr" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/aws-sdk-go/aws" - "github.com/input-output-hk/catalyst-forge/cli/internal/testutils" - "github.com/input-output-hk/catalyst-forge/cli/pkg/providers/aws/mocks" - "github.com/input-output-hk/catalyst-forge/lib/project/project" - sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" - sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" + "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" + "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" "github.com/stretchr/testify/assert" ) func TestECRClient_CreateECRRepository(t *testing.T) { - newProject := func(repo, path string) *project.Project { - return &project.Project{ - Blueprint: sb.Blueprint{ - Global: &sg.Global{ - Repo: &sg.Repo{ - Name: repo, - }, - }, - }, - Path: path, - } - } - tests := []struct { name string repo string - project *project.Project + path string fail bool validate func(t *testing.T, params *ecr.CreateRepositoryInput, err error) }{ { - name: "simple", - repo: "myapp", - project: newProject("myapp", "/path/to/myapp"), + name: "simple", + repo: "myapp", + path: "/path/to/myapp", validate: func(t *testing.T, params *ecr.CreateRepositoryInput, err error) { assert.NoError(t, err) assert.Equal(t, "myapp", *params.RepositoryName) @@ -55,10 +39,10 @@ func TestECRClient_CreateECRRepository(t *testing.T) { }, }, { - name: "failed", - repo: "myapp", - project: newProject("myapp", "/path/to/myapp"), - fail: true, + name: "failed", + repo: "myapp", + path: "/path/to/myapp", + fail: true, validate: func(t *testing.T, params *ecr.CreateRepositoryInput, err error) { assert.Error(t, err) }, @@ -85,7 +69,7 @@ func TestECRClient_CreateECRRepository(t *testing.T) { logger: testutils.NewNoopLogger(), } - err := client.CreateECRRepository(tt.project, tt.repo) + err := client.CreateECRRepository(tt.repo, tt.repo, tt.path) tt.validate(t, pp, err) }) } diff --git a/cli/pkg/providers/aws/mocks/ecr.go b/lib/providers/aws/mocks/ecr.go similarity index 100% rename from cli/pkg/providers/aws/mocks/ecr.go rename to lib/providers/aws/mocks/ecr.go diff --git a/cli/pkg/providers/aws/mocks/s3.go b/lib/providers/aws/mocks/s3.go similarity index 100% rename from cli/pkg/providers/aws/mocks/s3.go rename to lib/providers/aws/mocks/s3.go diff --git a/cli/pkg/providers/aws/s3.go b/lib/providers/aws/s3.go similarity index 100% rename from cli/pkg/providers/aws/s3.go rename to lib/providers/aws/s3.go diff --git a/lib/providers/blueprint.cue b/lib/providers/blueprint.cue new file mode 100644 index 00000000..acd6ce1b --- /dev/null +++ b/lib/providers/blueprint.cue @@ -0,0 +1 @@ +project: name: "blueprint" diff --git a/lib/project/providers/earthly.go b/lib/providers/earthly/earthly.go similarity index 94% rename from lib/project/providers/earthly.go rename to lib/providers/earthly/earthly.go index 79153c1f..7486866b 100644 --- a/lib/project/providers/earthly.go +++ b/lib/providers/earthly/earthly.go @@ -1,11 +1,11 @@ -package providers +package earthly import ( "fmt" "log/slog" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // EarthlyProviderCreds is the struct that holds the credentials for the Earthly provider. diff --git a/lib/tools/git/branch.go b/lib/providers/git/branch.go similarity index 62% rename from lib/tools/git/branch.go rename to lib/providers/git/branch.go index 6967728a..f820d6e2 100644 --- a/lib/tools/git/branch.go +++ b/lib/providers/git/branch.go @@ -3,7 +3,7 @@ package git import ( "fmt" - "github.com/input-output-hk/catalyst-forge/lib/tools/git/github" + "github.com/input-output-hk/catalyst-forge/lib/providers/github" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) @@ -12,10 +12,13 @@ var ( ) func GetBranch(repo *repo.GitRepo) (string, error) { - env := github.NewGithubEnv(nil) + gc, err := github.NewDefaultGithubClient("", "") + if err != nil { + return "", fmt.Errorf("failed to create github client: %w", err) + } if github.InCI() { - ref := env.GetBranch() + ref := gc.Env().GetBranch() if ref != "" { return ref, nil } diff --git a/lib/project/providers/git.go b/lib/providers/git/git.go similarity index 90% rename from lib/project/providers/git.go rename to lib/providers/git/git.go index 8cedb5df..70e3f3bf 100644 --- a/lib/project/providers/git.go +++ b/lib/providers/git/git.go @@ -1,11 +1,11 @@ -package providers +package git import ( "fmt" "log/slog" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // GitProviderCreds is the struct that holds the credentials for the Git provider diff --git a/lib/tools/git/tag.go b/lib/providers/git/tag.go similarity index 67% rename from lib/tools/git/tag.go rename to lib/providers/git/tag.go index da2b5809..ff437bd0 100644 --- a/lib/tools/git/tag.go +++ b/lib/providers/git/tag.go @@ -3,7 +3,7 @@ package git import ( "fmt" - "github.com/input-output-hk/catalyst-forge/lib/tools/git/github" + "github.com/input-output-hk/catalyst-forge/lib/providers/github" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) @@ -15,10 +15,13 @@ var ( func GetTag(r *repo.GitRepo) (string, error) { var tag string var err error - env := github.NewGithubEnv(nil) + gc, err := github.NewDefaultGithubClient("", "") + if err != nil { + return "", fmt.Errorf("failed to create github client: %w", err) + } if github.InCI() { - tag = env.GetTag() + tag = gc.Env().GetTag() if tag == "" { return "", ErrTagNotFound } diff --git a/lib/tools/git/util.go b/lib/providers/git/util.go similarity index 100% rename from lib/tools/git/util.go rename to lib/providers/git/util.go diff --git a/lib/tools/git/util_test.go b/lib/providers/git/util_test.go similarity index 100% rename from lib/tools/git/util_test.go rename to lib/providers/git/util_test.go diff --git a/lib/providers/github/client.go b/lib/providers/github/client.go new file mode 100644 index 00000000..4582291e --- /dev/null +++ b/lib/providers/github/client.go @@ -0,0 +1,278 @@ +package github + +import ( + "context" + "fmt" + "io" + "log/slog" + "mime" + "path/filepath" + + "github.com/google/go-github/v66/github" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" +) + +var ( + ErrNoGitHubToken = fmt.Errorf("no GitHub token found") + ErrNoRepository = fmt.Errorf("no repository information found") + ErrInvalidPR = fmt.Errorf("invalid pull request number") + ErrReleaseNotFound = fmt.Errorf("release not found") +) + +//go:generate go run github.com/matryer/moq@latest -skip-ensure --pkg mocks -out mocks/github.go . GithubClient + +// GithubClient is the interface for the Github client. +type GithubClient interface { + CreateRelease(opts *github.RepositoryRelease) (*github.RepositoryRelease, error) + Env() *GithubEnv + GetReleaseByTag(tag string) (*github.RepositoryRelease, error) + ListPullRequestComments(prNumber int) ([]PullRequestComment, error) + PostPullRequestComment(prNumber int, body string) error + ListBranches() ([]Branch, error) + UploadReleaseAsset(releaseID int64, path string) error +} + +// DefaultGithubClient is the default implementation of the Github client. +type DefaultGithubClient struct { + client *github.Client + env *GithubEnv + fs fs.Filesystem + logger *slog.Logger + opts *DefaultGithubClientOptions + Owner string + RepoName string + secretStore *secrets.SecretStore +} + +// Branch represents a Git branch in the repository. +type Branch struct { + Name string + CommitSHA string + Protected bool +} + +// PullRequestComment is a comment on a pull request. +type PullRequestComment struct { + Author string + Body string +} + +// Env returns the Github environment. +func (g *DefaultGithubClient) Env() *GithubEnv { + return g.env +} + +// CreateRelease creates a new release. +func (g *DefaultGithubClient) CreateRelease(opts *github.RepositoryRelease) (*github.RepositoryRelease, error) { + g.logger.Info("Creating release", "name", opts.Name) + release, _, err := g.client.Repositories.CreateRelease(context.Background(), g.Owner, g.RepoName, opts) + return release, err +} + +// ListPullRequestComments lists comments for a pull request. +func (g *DefaultGithubClient) ListPullRequestComments(prNumber int) ([]PullRequestComment, error) { + var all []PullRequestComment + ctx := context.Background() + opts := &github.IssueListCommentsOptions{ + ListOptions: github.ListOptions{PerPage: 100}, + } + + for { + g.logger.Debug("Fetching PR comments page", + "owner", g.Owner, "repo", g.RepoName, "pr", prNumber, "page", opts.Page) + comments, resp, err := g.client.Issues.ListComments(ctx, g.Owner, g.RepoName, prNumber, opts) + if err != nil { + return nil, fmt.Errorf("failed to list comments: %w", err) + } + + for _, c := range comments { + author := "" + if c.User != nil && c.User.Login != nil { + author = *c.User.Login + } + body := "" + if c.Body != nil { + body = *c.Body + } + all = append(all, PullRequestComment{ + Author: author, + Body: body, + }) + } + + // Break out when we've reached the last page. + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + + return all, nil +} + +// GetReleaseByTag gets a release by tag. +func (g *DefaultGithubClient) GetReleaseByTag(tag string) (*github.RepositoryRelease, error) { + release, resp, err := g.client.Repositories.GetReleaseByTag(context.Background(), g.Owner, g.RepoName, tag) + if resp.StatusCode == 404 { + return nil, ErrReleaseNotFound + } + return release, err +} + +// PostPullRequestComment posts a comment to a pull request. +func (g *DefaultGithubClient) PostPullRequestComment(prNumber int, body string) error { + if prNumber <= 0 { + return ErrInvalidPR + } + + if body == "" { + return fmt.Errorf("comment body cannot be empty") + } + + comment := &github.IssueComment{ + Body: &body, + } + + g.logger.Debug("Posting comment to PR", "owner", g.Owner, "repo", g.RepoName, "pr", prNumber) + _, _, err := g.client.Issues.CreateComment(context.Background(), g.Owner, g.RepoName, prNumber, comment) + if err != nil { + return fmt.Errorf("failed to post comment: %w", err) + } + + g.logger.Info("Successfully posted comment to PR", "owner", g.Owner, "repo", g.RepoName, "pr", prNumber) + return nil +} + +// ListBranches lists all branches in the repository. +func (g *DefaultGithubClient) ListBranches() ([]Branch, error) { + var all []Branch + ctx := context.Background() + opts := &github.BranchListOptions{ + ListOptions: github.ListOptions{PerPage: 100}, + } + + for { + g.logger.Debug("Fetching branches page", + "owner", g.Owner, "repo", g.RepoName, "page", opts.Page) + branches, resp, err := g.client.Repositories.ListBranches(ctx, g.Owner, g.RepoName, opts) + if err != nil { + return nil, fmt.Errorf("failed to list branches: %w", err) + } + + for _, b := range branches { + name := "" + if b.Name != nil { + name = *b.Name + } + + commitSHA := "" + if b.Commit != nil && b.Commit.SHA != nil { + commitSHA = *b.Commit.SHA + } + + all = append(all, Branch{ + Name: name, + CommitSHA: commitSHA, + Protected: b.GetProtected(), + }) + } + + // Break out when we've reached the last page. + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + + return all, nil +} + +// UploadReleaseAsset uploads a release asset to the given release. +func (g *DefaultGithubClient) UploadReleaseAsset(releaseID int64, path string) error { + f, err := g.fs.Open(path) + if err != nil { + return fmt.Errorf("failed to open release asset: %w", err) + } + defer f.Close() + + stat, err := f.Stat() + if err != nil { + return fmt.Errorf("failed to stat asset: %w", err) + } + + asset := filepath.Base(path) + contentType := mime.TypeByExtension(filepath.Ext(asset)) + if contentType == "" { + contentType = "application/octet-stream" + } + + url := fmt.Sprintf("repos/%s/%s/releases/%d/assets?name=%s", g.Owner, g.RepoName, releaseID, asset) + req, err := g.client.NewUploadRequest(url, f, stat.Size(), contentType) + if err != nil { + return fmt.Errorf("failed to create upload request: %w", err) + } + + _, err = g.client.Do(context.Background(), req, nil) + if err != nil { + return fmt.Errorf("failed to upload asset: %w", err) + } + + return nil +} + +// NewDefaultGithubClient creates a new DefaultGithubClient with a *github.Client and repository owner and name. +func NewDefaultGithubClient(owner, repoName string, opts ...DefaultGithubClientOption) (*DefaultGithubClient, error) { + gc := &DefaultGithubClient{ + opts: &DefaultGithubClientOptions{}, + } + for _, opt := range opts { + opt(gc) + } + + if gc.logger == nil { + gc.logger = slog.New(slog.NewTextHandler(io.Discard, nil)) + } + + if gc.fs == nil { + gc.fs = billy.NewBaseOsFS() + } + + if gc.client == nil { + if gc.opts.Token != "" { + gc.client = github.NewClient(nil).WithAuthToken(gc.opts.Token) + } else if gc.opts.Creds != nil { + if gc.secretStore == nil { + ss := secrets.NewDefaultSecretStore() + gc.secretStore = &ss + } + + creds, err := getGithubProviderCreds(gc.opts.Creds, gc.secretStore, gc.logger) + if err != nil { + return nil, fmt.Errorf("could not get Github provider credentials: %w", err) + } + gc.client = github.NewClient(nil).WithAuthToken(creds.Token) + } else { + gc.client = github.NewClient(nil) + } + } + + if gc.env == nil { + gc.env = &GithubEnv{ + fs: gc.fs, + logger: gc.logger, + } + } + + return &DefaultGithubClient{ + client: gc.client, + env: gc.env, + fs: gc.fs, + logger: gc.logger, + opts: gc.opts, + Owner: owner, + RepoName: repoName, + secretStore: gc.secretStore, + }, nil +} diff --git a/lib/providers/github/creds.go b/lib/providers/github/creds.go new file mode 100644 index 00000000..74ba68bf --- /dev/null +++ b/lib/providers/github/creds.go @@ -0,0 +1,29 @@ +package github + +import ( + "fmt" + "log/slog" + + "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" +) + +// GithubProviderCreds is the struct that holds the credentials for the Github provider +type GithubProviderCreds struct { + Token string +} + +// getGithubProviderCreds loads the Github provider credentials from the project. +func getGithubProviderCreds(s *common.Secret, ss *secrets.SecretStore, logger *slog.Logger) (GithubProviderCreds, error) { + m, err := secrets.GetSecretMap(s, ss, logger) + if err != nil { + return GithubProviderCreds{}, fmt.Errorf("could not get secret: %w", err) + } + + creds, ok := m["token"] + if !ok { + return GithubProviderCreds{}, fmt.Errorf("github provider token is missing in secret") + } + + return GithubProviderCreds{Token: creds}, nil +} diff --git a/lib/tools/git/github/env.go b/lib/providers/github/env.go similarity index 84% rename from lib/tools/git/github/env.go rename to lib/providers/github/env.go index b2854a02..861e358b 100644 --- a/lib/tools/git/github/env.go +++ b/lib/providers/github/env.go @@ -2,7 +2,6 @@ package github import ( "fmt" - "io" "log/slog" "os" "strconv" @@ -10,7 +9,6 @@ import ( "github.com/google/go-github/v66/github" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" - "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" ) var ( @@ -125,30 +123,6 @@ func (g *GithubEnv) HasEvent() bool { return pathExists && nameExists } -// NewGithubEnv creates a new GithubEnv. -func NewGithubEnv(logger *slog.Logger) GithubEnv { - if logger == nil { - logger = slog.New(slog.NewTextHandler(io.Discard, nil)) - } - - return GithubEnv{ - fs: billy.NewBaseOsFS(), - logger: logger, - } -} - -// NewCustomGithubEnv creates a new GithubEnv with a custom filesystem. -func NewCustomGithubEnv(fs fs.Filesystem, logger *slog.Logger) GithubEnv { - if logger == nil { - logger = slog.New(slog.NewTextHandler(io.Discard, nil)) - } - - return GithubEnv{ - fs: fs, - logger: logger, - } -} - // InCI returns whether the code is running in a CI environment. func InCI() bool { if _, ok := os.LookupEnv("GITHUB_ACTIONS"); ok { diff --git a/lib/tools/git/github/env_test.go b/lib/providers/github/env_test.go similarity index 100% rename from lib/tools/git/github/env_test.go rename to lib/providers/github/env_test.go diff --git a/lib/providers/github/mocks/github.go b/lib/providers/github/mocks/github.go new file mode 100644 index 00000000..0d5e02ea --- /dev/null +++ b/lib/providers/github/mocks/github.go @@ -0,0 +1,334 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package mocks + +import ( + v66github "github.com/google/go-github/v66/github" + providersgithub "github.com/input-output-hk/catalyst-forge/lib/providers/github" + "sync" +) + +// GithubClientMock is a mock implementation of github.GithubClient. +// +// func TestSomethingThatUsesGithubClient(t *testing.T) { +// +// // make and configure a mocked github.GithubClient +// mockedGithubClient := &GithubClientMock{ +// CreateReleaseFunc: func(opts *v66github.RepositoryRelease) (*v66github.RepositoryRelease, error) { +// panic("mock out the CreateRelease method") +// }, +// EnvFunc: func() *providersgithub.GithubEnv { +// panic("mock out the Env method") +// }, +// GetReleaseByTagFunc: func(tag string) (*v66github.RepositoryRelease, error) { +// panic("mock out the GetReleaseByTag method") +// }, +// ListBranchesFunc: func() ([]providersgithub.Branch, error) { +// panic("mock out the ListBranches method") +// }, +// ListPullRequestCommentsFunc: func(prNumber int) ([]providersgithub.PullRequestComment, error) { +// panic("mock out the ListPullRequestComments method") +// }, +// PostPullRequestCommentFunc: func(prNumber int, body string) error { +// panic("mock out the PostPullRequestComment method") +// }, +// UploadReleaseAssetFunc: func(releaseID int64, path string) error { +// panic("mock out the UploadReleaseAsset method") +// }, +// } +// +// // use mockedGithubClient in code that requires github.GithubClient +// // and then make assertions. +// +// } +type GithubClientMock struct { + // CreateReleaseFunc mocks the CreateRelease method. + CreateReleaseFunc func(opts *v66github.RepositoryRelease) (*v66github.RepositoryRelease, error) + + // EnvFunc mocks the Env method. + EnvFunc func() *providersgithub.GithubEnv + + // GetReleaseByTagFunc mocks the GetReleaseByTag method. + GetReleaseByTagFunc func(tag string) (*v66github.RepositoryRelease, error) + + // ListBranchesFunc mocks the ListBranches method. + ListBranchesFunc func() ([]providersgithub.Branch, error) + + // ListPullRequestCommentsFunc mocks the ListPullRequestComments method. + ListPullRequestCommentsFunc func(prNumber int) ([]providersgithub.PullRequestComment, error) + + // PostPullRequestCommentFunc mocks the PostPullRequestComment method. + PostPullRequestCommentFunc func(prNumber int, body string) error + + // UploadReleaseAssetFunc mocks the UploadReleaseAsset method. + UploadReleaseAssetFunc func(releaseID int64, path string) error + + // calls tracks calls to the methods. + calls struct { + // CreateRelease holds details about calls to the CreateRelease method. + CreateRelease []struct { + // Opts is the opts argument value. + Opts *v66github.RepositoryRelease + } + // Env holds details about calls to the Env method. + Env []struct { + } + // GetReleaseByTag holds details about calls to the GetReleaseByTag method. + GetReleaseByTag []struct { + // Tag is the tag argument value. + Tag string + } + // ListBranches holds details about calls to the ListBranches method. + ListBranches []struct { + } + // ListPullRequestComments holds details about calls to the ListPullRequestComments method. + ListPullRequestComments []struct { + // PrNumber is the prNumber argument value. + PrNumber int + } + // PostPullRequestComment holds details about calls to the PostPullRequestComment method. + PostPullRequestComment []struct { + // PrNumber is the prNumber argument value. + PrNumber int + // Body is the body argument value. + Body string + } + // UploadReleaseAsset holds details about calls to the UploadReleaseAsset method. + UploadReleaseAsset []struct { + // ReleaseID is the releaseID argument value. + ReleaseID int64 + // Path is the path argument value. + Path string + } + } + lockCreateRelease sync.RWMutex + lockEnv sync.RWMutex + lockGetReleaseByTag sync.RWMutex + lockListBranches sync.RWMutex + lockListPullRequestComments sync.RWMutex + lockPostPullRequestComment sync.RWMutex + lockUploadReleaseAsset sync.RWMutex +} + +// CreateRelease calls CreateReleaseFunc. +func (mock *GithubClientMock) CreateRelease(opts *v66github.RepositoryRelease) (*v66github.RepositoryRelease, error) { + if mock.CreateReleaseFunc == nil { + panic("GithubClientMock.CreateReleaseFunc: method is nil but GithubClient.CreateRelease was just called") + } + callInfo := struct { + Opts *v66github.RepositoryRelease + }{ + Opts: opts, + } + mock.lockCreateRelease.Lock() + mock.calls.CreateRelease = append(mock.calls.CreateRelease, callInfo) + mock.lockCreateRelease.Unlock() + return mock.CreateReleaseFunc(opts) +} + +// CreateReleaseCalls gets all the calls that were made to CreateRelease. +// Check the length with: +// +// len(mockedGithubClient.CreateReleaseCalls()) +func (mock *GithubClientMock) CreateReleaseCalls() []struct { + Opts *v66github.RepositoryRelease +} { + var calls []struct { + Opts *v66github.RepositoryRelease + } + mock.lockCreateRelease.RLock() + calls = mock.calls.CreateRelease + mock.lockCreateRelease.RUnlock() + return calls +} + +// Env calls EnvFunc. +func (mock *GithubClientMock) Env() *providersgithub.GithubEnv { + if mock.EnvFunc == nil { + panic("GithubClientMock.EnvFunc: method is nil but GithubClient.Env was just called") + } + callInfo := struct { + }{} + mock.lockEnv.Lock() + mock.calls.Env = append(mock.calls.Env, callInfo) + mock.lockEnv.Unlock() + return mock.EnvFunc() +} + +// EnvCalls gets all the calls that were made to Env. +// Check the length with: +// +// len(mockedGithubClient.EnvCalls()) +func (mock *GithubClientMock) EnvCalls() []struct { +} { + var calls []struct { + } + mock.lockEnv.RLock() + calls = mock.calls.Env + mock.lockEnv.RUnlock() + return calls +} + +// GetReleaseByTag calls GetReleaseByTagFunc. +func (mock *GithubClientMock) GetReleaseByTag(tag string) (*v66github.RepositoryRelease, error) { + if mock.GetReleaseByTagFunc == nil { + panic("GithubClientMock.GetReleaseByTagFunc: method is nil but GithubClient.GetReleaseByTag was just called") + } + callInfo := struct { + Tag string + }{ + Tag: tag, + } + mock.lockGetReleaseByTag.Lock() + mock.calls.GetReleaseByTag = append(mock.calls.GetReleaseByTag, callInfo) + mock.lockGetReleaseByTag.Unlock() + return mock.GetReleaseByTagFunc(tag) +} + +// GetReleaseByTagCalls gets all the calls that were made to GetReleaseByTag. +// Check the length with: +// +// len(mockedGithubClient.GetReleaseByTagCalls()) +func (mock *GithubClientMock) GetReleaseByTagCalls() []struct { + Tag string +} { + var calls []struct { + Tag string + } + mock.lockGetReleaseByTag.RLock() + calls = mock.calls.GetReleaseByTag + mock.lockGetReleaseByTag.RUnlock() + return calls +} + +// ListBranches calls ListBranchesFunc. +func (mock *GithubClientMock) ListBranches() ([]providersgithub.Branch, error) { + if mock.ListBranchesFunc == nil { + panic("GithubClientMock.ListBranchesFunc: method is nil but GithubClient.ListBranches was just called") + } + callInfo := struct { + }{} + mock.lockListBranches.Lock() + mock.calls.ListBranches = append(mock.calls.ListBranches, callInfo) + mock.lockListBranches.Unlock() + return mock.ListBranchesFunc() +} + +// ListBranchesCalls gets all the calls that were made to ListBranches. +// Check the length with: +// +// len(mockedGithubClient.ListBranchesCalls()) +func (mock *GithubClientMock) ListBranchesCalls() []struct { +} { + var calls []struct { + } + mock.lockListBranches.RLock() + calls = mock.calls.ListBranches + mock.lockListBranches.RUnlock() + return calls +} + +// ListPullRequestComments calls ListPullRequestCommentsFunc. +func (mock *GithubClientMock) ListPullRequestComments(prNumber int) ([]providersgithub.PullRequestComment, error) { + if mock.ListPullRequestCommentsFunc == nil { + panic("GithubClientMock.ListPullRequestCommentsFunc: method is nil but GithubClient.ListPullRequestComments was just called") + } + callInfo := struct { + PrNumber int + }{ + PrNumber: prNumber, + } + mock.lockListPullRequestComments.Lock() + mock.calls.ListPullRequestComments = append(mock.calls.ListPullRequestComments, callInfo) + mock.lockListPullRequestComments.Unlock() + return mock.ListPullRequestCommentsFunc(prNumber) +} + +// ListPullRequestCommentsCalls gets all the calls that were made to ListPullRequestComments. +// Check the length with: +// +// len(mockedGithubClient.ListPullRequestCommentsCalls()) +func (mock *GithubClientMock) ListPullRequestCommentsCalls() []struct { + PrNumber int +} { + var calls []struct { + PrNumber int + } + mock.lockListPullRequestComments.RLock() + calls = mock.calls.ListPullRequestComments + mock.lockListPullRequestComments.RUnlock() + return calls +} + +// PostPullRequestComment calls PostPullRequestCommentFunc. +func (mock *GithubClientMock) PostPullRequestComment(prNumber int, body string) error { + if mock.PostPullRequestCommentFunc == nil { + panic("GithubClientMock.PostPullRequestCommentFunc: method is nil but GithubClient.PostPullRequestComment was just called") + } + callInfo := struct { + PrNumber int + Body string + }{ + PrNumber: prNumber, + Body: body, + } + mock.lockPostPullRequestComment.Lock() + mock.calls.PostPullRequestComment = append(mock.calls.PostPullRequestComment, callInfo) + mock.lockPostPullRequestComment.Unlock() + return mock.PostPullRequestCommentFunc(prNumber, body) +} + +// PostPullRequestCommentCalls gets all the calls that were made to PostPullRequestComment. +// Check the length with: +// +// len(mockedGithubClient.PostPullRequestCommentCalls()) +func (mock *GithubClientMock) PostPullRequestCommentCalls() []struct { + PrNumber int + Body string +} { + var calls []struct { + PrNumber int + Body string + } + mock.lockPostPullRequestComment.RLock() + calls = mock.calls.PostPullRequestComment + mock.lockPostPullRequestComment.RUnlock() + return calls +} + +// UploadReleaseAsset calls UploadReleaseAssetFunc. +func (mock *GithubClientMock) UploadReleaseAsset(releaseID int64, path string) error { + if mock.UploadReleaseAssetFunc == nil { + panic("GithubClientMock.UploadReleaseAssetFunc: method is nil but GithubClient.UploadReleaseAsset was just called") + } + callInfo := struct { + ReleaseID int64 + Path string + }{ + ReleaseID: releaseID, + Path: path, + } + mock.lockUploadReleaseAsset.Lock() + mock.calls.UploadReleaseAsset = append(mock.calls.UploadReleaseAsset, callInfo) + mock.lockUploadReleaseAsset.Unlock() + return mock.UploadReleaseAssetFunc(releaseID, path) +} + +// UploadReleaseAssetCalls gets all the calls that were made to UploadReleaseAsset. +// Check the length with: +// +// len(mockedGithubClient.UploadReleaseAssetCalls()) +func (mock *GithubClientMock) UploadReleaseAssetCalls() []struct { + ReleaseID int64 + Path string +} { + var calls []struct { + ReleaseID int64 + Path string + } + mock.lockUploadReleaseAsset.RLock() + calls = mock.calls.UploadReleaseAsset + mock.lockUploadReleaseAsset.RUnlock() + return calls +} diff --git a/lib/providers/github/opts.go b/lib/providers/github/opts.go new file mode 100644 index 00000000..7b32423c --- /dev/null +++ b/lib/providers/github/opts.go @@ -0,0 +1,75 @@ +package github + +import ( + "log/slog" + "os" + + "github.com/google/go-github/v66/github" + "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/tools/fs" +) + +type DefaultGithubClientOption func(*DefaultGithubClient) +type DefaultGithubClientOptions struct { + Creds *common.Secret + Token string +} + +// WithCreds sets the credentials for the Github client. +func WithCreds(creds *common.Secret) DefaultGithubClientOption { + return func(c *DefaultGithubClient) { + c.opts.Creds = creds + } +} + +// WithCredsOrEnv sets the credentials for the Github client. +// If a GITHUB_TOKEN environment variable is set, it will use that token. +// Otherwise, it will use the given secret. +func WithCredsOrEnv(creds *common.Secret) DefaultGithubClientOption { + token, exists := os.LookupEnv("GITHUB_TOKEN") + if exists { + return func(c *DefaultGithubClient) { + c.opts.Token = token + } + } + + return func(c *DefaultGithubClient) { + c.opts.Creds = creds + } +} + +// WithFs sets the filesystem for the Github client. +func WithFs(fs fs.Filesystem) DefaultGithubClientOption { + return func(c *DefaultGithubClient) { + c.fs = fs + } +} + +// WithGithubEnv sets the Github environment for the Github client. +func WithGithubEnv(env *GithubEnv) DefaultGithubClientOption { + return func(c *DefaultGithubClient) { + c.env = env + } +} + +// WithGithubClient sets the native Github client for the Github client. +func WithGithubClient(client *github.Client) DefaultGithubClientOption { + return func(c *DefaultGithubClient) { + c.client = client + } +} + +// WithLogger sets the logger for the Github client. +func WithLogger(logger *slog.Logger) DefaultGithubClientOption { + return func(c *DefaultGithubClient) { + c.logger = logger + } +} + +// WithSecretStore sets the secret store for the Github client. +func WithSecretStore(ss *secrets.SecretStore) DefaultGithubClientOption { + return func(c *DefaultGithubClient) { + c.secretStore = ss + } +} diff --git a/lib/tools/git/github/testdata/event.json b/lib/providers/github/testdata/event.json similarity index 100% rename from lib/tools/git/github/testdata/event.json rename to lib/providers/github/testdata/event.json diff --git a/lib/providers/go.mod b/lib/providers/go.mod new file mode 100644 index 00000000..8a372dfb --- /dev/null +++ b/lib/providers/go.mod @@ -0,0 +1,66 @@ +module github.com/input-output-hk/catalyst-forge/lib/providers + +go 1.24.2 + +replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema + +replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../secrets + +replace github.com/input-output-hk/catalyst-forge/lib/tools => ../tools + +require ( + github.com/aws/aws-sdk-go v1.55.7 + github.com/aws/aws-sdk-go-v2 v1.36.6 + github.com/aws/aws-sdk-go-v2/config v1.29.18 + github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1 + github.com/google/go-github/v66 v66.0.0 + github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0-00010101000000-000000000000 + github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 + github.com/stretchr/testify v1.10.0 +) + +require ( + dario.cat/mergo v1.0.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/adrg/xdg v0.5.3 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.12.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.29.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/lib/providers/go.sum b/lib/providers/go.sum new file mode 100644 index 00000000..a01b2286 --- /dev/null +++ b/lib/providers/go.sum @@ -0,0 +1,193 @@ +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= +github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU= +github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= +github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I= +github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.37 h1:XTZZ0I3SZUHAtBLBU6395ad+VOblE0DwQP6MuaNeics= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.37/go.mod h1:Pi6ksbniAWVwu2S8pEzcYPyhUkAcLaufxN7PfAUQjBk= +github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0 h1:oyXvdONSO/VmFwEupTO+P5AFFghpNyM2MeYi7FARciM= +github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0/go.mod h1:uDcrAwhZkHtPAFst5Wx7WSAhMi8BvVegEkc0Kg16vUM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5 h1:M5/B8JUaCI8+9QD+u3S/f4YHpvqE9RpSkV3rf0Iks2w= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5/go.mod h1:Bktzci1bwdbpuLiu3AOksiNPMl/LLKmX1TWmqp2xbvs= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18 h1:OS2e0SKqsU2LiJPqL8u9x41tKc6MMEHrWjLVLn3oysg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18/go.mod h1:+Yrk+MDGzlNGxCXieljNeWpoZTCQUQVL+Jk9hGGJ8qM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1 h1:RkHXU9jP0DptGy7qKI8CBGsUJruWz0v5IgwBa2DwWcU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1/go.mod h1:3xAOf7tdKF+qbb+XpU+EPhNXAdun3Lu1RcDrj8KC24I= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 h1:HD6R8K10gPbN9CNqRDOs42QombXlYeLOr4KkIxe2lQs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8/go.mod h1:x66GdH8qjYTr6Kb4ik38Ewl6moLsg8igbceNsmxVxeA= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M= +github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib/schema/Earthfile b/lib/schema/Earthfile index 2c65772f..ff75e82a 100644 --- a/lib/schema/Earthfile +++ b/lib/schema/Earthfile @@ -1,7 +1,7 @@ VERSION 0.8 deps: - FROM golang:1.24.0-bookworm + FROM golang:1.24.2-bookworm WORKDIR /work diff --git a/lib/schema/go.mod b/lib/schema/go.mod index 1ddab7d6..2e38b7f5 100644 --- a/lib/schema/go.mod +++ b/lib/schema/go.mod @@ -1,11 +1,10 @@ module github.com/input-output-hk/catalyst-forge/lib/schema -go 1.23.0 +go 1.24.2 require ( cuelang.org/go v0.12.0 github.com/Masterminds/semver/v3 v3.3.1 - github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 ) require ( @@ -21,6 +20,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d // indirect github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a // indirect + github.com/stretchr/testify v1.10.0 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect diff --git a/lib/schema/go.sum b/lib/schema/go.sum index 65444768..e79d1fd6 100644 --- a/lib/schema/go.sum +++ b/lib/schema/go.sum @@ -2,46 +2,20 @@ cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 h1:mRwydyTyhtR cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= cuelang.org/go v0.12.0 h1:q4W5I+RtDIA27rslQyyt6sWkXX0YS9qm43+U1/3e0kU= cuelang.org/go v0.12.0/go.mod h1:B4+kjvGGQnbkz+GuAv1dq/R308gTkp0sO28FdMrJ2Kw= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= -github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/proto v1.13.4 h1:myn1fyf8t7tAqIzV91Tj9qXpvyXXGXk8OS2H6IBSc9g= github.com/emicklei/proto v1.13.4/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -58,24 +32,14 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA= github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= @@ -93,7 +57,5 @@ golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib/secrets/.earthlyignore b/lib/secrets/.earthlyignore new file mode 100644 index 00000000..3d720b45 --- /dev/null +++ b/lib/secrets/.earthlyignore @@ -0,0 +1,4 @@ +Earthfile +README.md +LICENSE-* +blueprint.cue \ No newline at end of file diff --git a/lib/secrets/Earthfile b/lib/secrets/Earthfile new file mode 100644 index 00000000..d43e1619 --- /dev/null +++ b/lib/secrets/Earthfile @@ -0,0 +1,39 @@ +VERSION 0.8 + +deps: + FROM golang:1.24.2-bookworm + + WORKDIR /work + + RUN mkdir -p /go/cache && mkdir -p /go/modcache + ENV GOCACHE=/go/cache + ENV GOMODCACHE=/go/modcache + CACHE --persist --sharing shared /go + + COPY ../schema+src/src /schema + COPY ../tools+src/src /tools + + COPY go.mod go.sum . + RUN go mod download + +src: + FROM +deps + + CACHE --persist --sharing shared /go + + COPY . . + + RUN go generate ./... + + SAVE ARTIFACT . src + +check: + FROM +src + + RUN gofmt -l . | grep . && exit 1 || exit 0 + RUN go vet ./... + +test: + FROM +src + + RUN go test ./... \ No newline at end of file diff --git a/lib/secrets/LICENSE-APACHE b/lib/secrets/LICENSE-APACHE new file mode 100644 index 00000000..a55761ab --- /dev/null +++ b/lib/secrets/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright (c) 2023 Input Output (IOG). + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/lib/secrets/LICENSE-MIT b/lib/secrets/LICENSE-MIT new file mode 100644 index 00000000..ac4df9c0 --- /dev/null +++ b/lib/secrets/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2024 Input Output (IOG). + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/secrets/blueprint.cue b/lib/secrets/blueprint.cue new file mode 100644 index 00000000..acd6ce1b --- /dev/null +++ b/lib/secrets/blueprint.cue @@ -0,0 +1 @@ +project: name: "blueprint" diff --git a/lib/project/secrets/client.go b/lib/secrets/client.go similarity index 94% rename from lib/project/secrets/client.go rename to lib/secrets/client.go index 7baa1899..f50d0f9e 100644 --- a/lib/project/secrets/client.go +++ b/lib/secrets/client.go @@ -4,7 +4,7 @@ import ( "fmt" "log/slog" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets/providers" + "github.com/input-output-hk/catalyst-forge/lib/secrets/providers" ) // SecretStore is a store of secret providers. diff --git a/lib/secrets/go.mod b/lib/secrets/go.mod new file mode 100644 index 00000000..8cad7d66 --- /dev/null +++ b/lib/secrets/go.mod @@ -0,0 +1,57 @@ +module github.com/input-output-hk/catalyst-forge/lib/secrets + +go 1.24.2 + +replace github.com/input-output-hk/catalyst-forge/lib/providers => ../providers + +replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema + +replace github.com/input-output-hk/catalyst-forge/lib/tools => ../tools + +require ( + github.com/aws/aws-sdk-go v1.55.7 + github.com/aws/aws-sdk-go-v2/config v1.29.18 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 + github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 + github.com/stretchr/testify v1.10.0 +) + +require ( + dario.cat/mergo v1.0.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/adrg/xdg v0.5.3 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.6 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.12.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.29.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/lib/secrets/go.sum b/lib/secrets/go.sum new file mode 100644 index 00000000..d3b10aa7 --- /dev/null +++ b/lib/secrets/go.sum @@ -0,0 +1,175 @@ +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= +github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU= +github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I= +github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 h1:HD6R8K10gPbN9CNqRDOs42QombXlYeLOr4KkIxe2lQs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8/go.mod h1:x66GdH8qjYTr6Kb4ik38Ewl6moLsg8igbceNsmxVxeA= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib/project/secrets/interface.go b/lib/secrets/interface.go similarity index 100% rename from lib/project/secrets/interface.go rename to lib/secrets/interface.go diff --git a/lib/project/secrets/mocks/interface_mock.go b/lib/secrets/mocks/interface_mock.go similarity index 97% rename from lib/project/secrets/mocks/interface_mock.go rename to lib/secrets/mocks/interface_mock.go index 07d4da62..ad2c244c 100644 --- a/lib/project/secrets/mocks/interface_mock.go +++ b/lib/secrets/mocks/interface_mock.go @@ -4,8 +4,9 @@ package mocks import ( - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" "sync" + + "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // Ensure, that SecretProviderMock does implement secrets.SecretProvider. diff --git a/lib/project/secrets/providers.go b/lib/secrets/providers.go similarity index 100% rename from lib/project/secrets/providers.go rename to lib/secrets/providers.go diff --git a/lib/project/secrets/providers/aws.go b/lib/secrets/providers/aws.go similarity index 100% rename from lib/project/secrets/providers/aws.go rename to lib/secrets/providers/aws.go diff --git a/lib/project/secrets/providers/aws_mock_test.go b/lib/secrets/providers/aws_mock_test.go similarity index 100% rename from lib/project/secrets/providers/aws_mock_test.go rename to lib/secrets/providers/aws_mock_test.go diff --git a/lib/project/secrets/providers/aws_test.go b/lib/secrets/providers/aws_test.go similarity index 100% rename from lib/project/secrets/providers/aws_test.go rename to lib/secrets/providers/aws_test.go diff --git a/lib/project/secrets/providers/env.go b/lib/secrets/providers/env.go similarity index 100% rename from lib/project/secrets/providers/env.go rename to lib/secrets/providers/env.go diff --git a/lib/project/secrets/providers/env_test.go b/lib/secrets/providers/env_test.go similarity index 100% rename from lib/project/secrets/providers/env_test.go rename to lib/secrets/providers/env_test.go diff --git a/lib/project/secrets/providers/local.go b/lib/secrets/providers/local.go similarity index 100% rename from lib/project/secrets/providers/local.go rename to lib/secrets/providers/local.go diff --git a/lib/project/secrets/providers/local_test.go b/lib/secrets/providers/local_test.go similarity index 100% rename from lib/project/secrets/providers/local_test.go rename to lib/secrets/providers/local_test.go diff --git a/lib/project/secrets/secrets.go b/lib/secrets/secrets.go similarity index 100% rename from lib/project/secrets/secrets.go rename to lib/secrets/secrets.go diff --git a/lib/tools/Earthfile b/lib/tools/Earthfile index ee2df254..03988b1b 100644 --- a/lib/tools/Earthfile +++ b/lib/tools/Earthfile @@ -1,7 +1,7 @@ VERSION 0.8 deps: - FROM golang:1.24.0-bookworm + FROM golang:1.24.2-bookworm WORKDIR /work diff --git a/lib/tools/git/github/client.go b/lib/tools/git/github/client.go deleted file mode 100644 index 7d8aab42..00000000 --- a/lib/tools/git/github/client.go +++ /dev/null @@ -1,155 +0,0 @@ -package github - -import ( - "context" - "fmt" - "log/slog" - - "github.com/google/go-github/v66/github" -) - -var ( - ErrNoGitHubToken = fmt.Errorf("no GitHub token found") - ErrNoRepository = fmt.Errorf("no repository information found") - ErrInvalidPR = fmt.Errorf("invalid pull request number") -) - -// GithubClient is a wrapper around the github client. -type GithubClient struct { - client *github.Client - logger *slog.Logger - owner string - repoName string -} - -// Branch represents a Git branch in the repository. -type Branch struct { - Name string - CommitSHA string - Protected bool -} - -// PullRequestComment is a comment on a pull request. -type PullRequestComment struct { - Author string - Body string -} - -// ListPullRequestComments lists comments for a pull request. -func (g *GithubClient) ListPullRequestComments(prNumber int) ([]PullRequestComment, error) { - var all []PullRequestComment - ctx := context.Background() - opts := &github.IssueListCommentsOptions{ - ListOptions: github.ListOptions{PerPage: 100}, - } - - for { - g.logger.Debug("Fetching PR comments page", - "owner", g.owner, "repo", g.repoName, "pr", prNumber, "page", opts.Page) - comments, resp, err := g.client.Issues.ListComments(ctx, g.owner, g.repoName, prNumber, opts) - if err != nil { - return nil, fmt.Errorf("failed to list comments: %w", err) - } - - for _, c := range comments { - author := "" - if c.User != nil && c.User.Login != nil { - author = *c.User.Login - } - body := "" - if c.Body != nil { - body = *c.Body - } - all = append(all, PullRequestComment{ - Author: author, - Body: body, - }) - } - - // Break out when we've reached the last page. - if resp.NextPage == 0 { - break - } - opts.Page = resp.NextPage - } - - return all, nil -} - -// PostPullRequestComment posts a comment to a pull request. -func (g *GithubClient) PostPullRequestComment(prNumber int, body string) error { - if prNumber <= 0 { - return ErrInvalidPR - } - - if body == "" { - return fmt.Errorf("comment body cannot be empty") - } - - comment := &github.IssueComment{ - Body: &body, - } - - g.logger.Debug("Posting comment to PR", "owner", g.owner, "repo", g.repoName, "pr", prNumber) - _, _, err := g.client.Issues.CreateComment(context.Background(), g.owner, g.repoName, prNumber, comment) - if err != nil { - return fmt.Errorf("failed to post comment: %w", err) - } - - g.logger.Info("Successfully posted comment to PR", "owner", g.owner, "repo", g.repoName, "pr", prNumber) - return nil -} - -// ListBranches lists all branches in the repository. -func (g *GithubClient) ListBranches() ([]Branch, error) { - var all []Branch - ctx := context.Background() - opts := &github.BranchListOptions{ - ListOptions: github.ListOptions{PerPage: 100}, - } - - for { - g.logger.Debug("Fetching branches page", - "owner", g.owner, "repo", g.repoName, "page", opts.Page) - branches, resp, err := g.client.Repositories.ListBranches(ctx, g.owner, g.repoName, opts) - if err != nil { - return nil, fmt.Errorf("failed to list branches: %w", err) - } - - for _, b := range branches { - name := "" - if b.Name != nil { - name = *b.Name - } - - commitSHA := "" - if b.Commit != nil && b.Commit.SHA != nil { - commitSHA = *b.Commit.SHA - } - - all = append(all, Branch{ - Name: name, - CommitSHA: commitSHA, - Protected: b.GetProtected(), - }) - } - - // Break out when we've reached the last page. - if resp.NextPage == 0 { - break - } - opts.Page = resp.NextPage - } - - return all, nil -} - -// NewGithubClient creates a new GithubClient with a *github.Client and repository owner and name. -func NewGithubClient(owner, repoName string, client *github.Client, logger *slog.Logger) GithubClient { - return GithubClient{ - client: client, - logger: logger, - owner: owner, - repoName: repoName, - } -} diff --git a/lib/tools/go.mod b/lib/tools/go.mod index a0c67009..fb14829b 100644 --- a/lib/tools/go.mod +++ b/lib/tools/go.mod @@ -1,48 +1,51 @@ module github.com/input-output-hk/catalyst-forge/lib/tools -go 1.22.3 +go 1.24.2 require ( - cuelang.org/go v0.10.0 + cuelang.org/go v0.12.0 github.com/Masterminds/semver/v3 v3.3.1 github.com/adrg/xdg v0.5.3 github.com/earthly/earthly/ast v0.0.2-0.20240228223838-42e8ca204e8a github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 - github.com/google/go-github/v66 v66.0.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 ) require ( - dario.cat/mergo v1.0.0 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + dario.cat/mergo v1.0.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230219212500-1f9a474cc2dc // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/input-output-hk/catalyst-forge/lib/providers => ../providers + +replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../secrets + +replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema diff --git a/lib/tools/go.sum b/lib/tools/go.sum index b8e42ab4..8da796e0 100644 --- a/lib/tools/go.sum +++ b/lib/tools/go.sum @@ -1,14 +1,14 @@ -cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79 h1:EceZITBGET3qHneD5xowSTY/YHbNybvMWGh62K2fG/M= -cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= -cuelang.org/go v0.10.0 h1:Y1Pu4wwga5HkXfLFK1sWAYaSWIBdcsr5Cb5AWj2pOuE= -cuelang.org/go v0.10.0/go.mod h1:HzlaqqqInHNiqE6slTP6+UtxT9hN6DAzgJgdbNxXvX8= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 h1:mRwydyTyhtRX2wXS3mqYWzR2qlv6KsmoKXmlz5vInjg= +cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= +cuelang.org/go v0.12.0 h1:q4W5I+RtDIA27rslQyyt6sWkXX0YS9qm43+U1/3e0kU= +cuelang.org/go v0.12.0/go.mod h1:B4+kjvGGQnbkz+GuAv1dq/R308gTkp0sO28FdMrJ2Kw= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= @@ -25,17 +25,18 @@ github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vc github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/earthly/earthly/ast v0.0.2-0.20240228223838-42e8ca204e8a h1:Z4oatniIQ8EG0JL26cX9cc7IeJUe9Zs7wFetMJpbEhY= github.com/earthly/earthly/ast v0.0.2-0.20240228223838-42e8ca204e8a/go.mod h1:74/Fa5yMVQdnD/a32pXf8CrzH6MfAaXNIFt15MoHuv0= github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= -github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.13.4 h1:myn1fyf8t7tAqIzV91Tj9qXpvyXXGXk8OS2H6IBSc9g= +github.com/emicklei/proto v1.13.4/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= @@ -52,13 +53,8 @@ github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7 github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M= -github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -82,18 +78,19 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4= -github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= -github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21 h1:igWZJluD8KtEtAgRyF4x6lqcxDry1ULztksMJh2mnQE= -github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21/go.mod h1:RMRJLmBOqWacUkmJHRMiPKh1S1m3PA7Zh4W80/kWPpg= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA= +github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -102,8 +99,8 @@ github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -112,14 +109,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -127,15 +124,15 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -149,15 +146,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -165,16 +162,15 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From a7a690c3b4fb7ddc79ae7b00869e6a3b1f44a230 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 17:37:23 -0700 Subject: [PATCH 23/29] wip: fixes foundry --- foundry/api/Earthfile | 2 +- foundry/operator/Earthfile | 4 +- foundry/operator/cmd/main.go | 6 +- foundry/operator/go.mod | 38 +++++++----- foundry/operator/go.sum | 60 +++++++++---------- .../internal/controller/release_controller.go | 2 +- .../internal/controller/suite_env_test.go | 2 +- 7 files changed, 61 insertions(+), 53 deletions(-) diff --git a/foundry/api/Earthfile b/foundry/api/Earthfile index a1acdd9f..9bcb5694 100644 --- a/foundry/api/Earthfile +++ b/foundry/api/Earthfile @@ -1,7 +1,7 @@ VERSION 0.8 deps: - FROM golang:1.24.0-bookworm + FROM golang:1.24.2-bookworm WORKDIR /work diff --git a/foundry/operator/Earthfile b/foundry/operator/Earthfile index d244f8f7..c48ab4ac 100644 --- a/foundry/operator/Earthfile +++ b/foundry/operator/Earthfile @@ -1,7 +1,7 @@ VERSION 0.8 deps: - FROM golang:1.24.0-bookworm + FROM golang:1.24.2-bookworm WORKDIR /work/operator ARG CONTROLLER_GEN_VERSION=v0.17.2 @@ -31,8 +31,10 @@ deps: # Copy local deps COPY ../api+src/src /work/api COPY ../../lib/project+src/src /lib/project + COPY ../../lib/providers+src/src /lib/providers COPY ../../lib/schema+src/src /lib/schema COPY ../../lib/tools+src/src /lib/tools + COPY ../../lib/secrets+src/src /lib/secrets # Install go deps RUN mkdir -p /go/cache && mkdir -p /go/modcache diff --git a/foundry/operator/cmd/main.go b/foundry/operator/cmd/main.go index bdeed3cd..259f5e62 100644 --- a/foundry/operator/cmd/main.go +++ b/foundry/operator/cmd/main.go @@ -47,8 +47,8 @@ import ( "github.com/input-output-hk/catalyst-forge/foundry/operator/pkg/config" "github.com/input-output-hk/catalyst-forge/foundry/operator/pkg/handlers" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" - "github.com/input-output-hk/catalyst-forge/lib/project/providers" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/git" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote" // +kubebuilder:scaffold:imports @@ -229,7 +229,7 @@ func main() { setupLog.Info("Fetching git auth token") secretStore := secrets.NewDefaultSecretStore() - creds, err := providers.GetGitProviderCreds(&cfg.Deployer.Git.Creds, &secretStore, logger) + creds, err := git.GetGitProviderCreds(&cfg.Deployer.Git.Creds, &secretStore, logger) if err != nil { setupLog.Error(err, "unable to get auth token") os.Exit(1) diff --git a/foundry/operator/go.mod b/foundry/operator/go.mod index 82e3dc1e..0a781051 100644 --- a/foundry/operator/go.mod +++ b/foundry/operator/go.mod @@ -1,6 +1,6 @@ module github.com/input-output-hk/catalyst-forge/foundry/operator -go 1.23.0 +go 1.24.2 godebug default=go1.23 @@ -11,7 +11,9 @@ require ( github.com/go-git/go-git/v5 v5.12.0 github.com/input-output-hk/catalyst-forge/foundry/api v0.0.0 github.com/input-output-hk/catalyst-forge/lib/project v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/providers v0.0.0 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 + github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 @@ -41,21 +43,21 @@ require ( github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230219212500-1f9a474cc2dc // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.55.5 // indirect - github.com/aws/aws-sdk-go-v2 v1.31.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.40 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.38 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.31.4 // indirect - github.com/aws/smithy-go v1.21.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.6 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.18 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect + github.com/aws/smithy-go v1.22.4 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -272,8 +274,12 @@ require ( replace github.com/input-output-hk/catalyst-forge/lib/project => ../../lib/project +replace github.com/input-output-hk/catalyst-forge/lib/providers => ../../lib/providers + replace github.com/input-output-hk/catalyst-forge/lib/schema => ../../lib/schema +replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../../lib/secrets + replace github.com/input-output-hk/catalyst-forge/lib/tools => ../../lib/tools replace github.com/input-output-hk/catalyst-forge/foundry/api => ../api diff --git a/foundry/operator/go.sum b/foundry/operator/go.sum index 30c26471..ff52574c 100644 --- a/foundry/operator/go.sum +++ b/foundry/operator/go.sum @@ -237,36 +237,36 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/config v1.27.40 h1:sie4mPBGFOO+Z27+yHzvyN31G20h/bf2xb5mCbpLv2Q= -github.com/aws/aws-sdk-go-v2/config v1.27.40/go.mod h1:4KW7Aa5tNo+0VHnuLnnE1vPHtwMurlNZNS65IdcewHA= -github.com/aws/aws-sdk-go-v2/credentials v1.17.38 h1:iM90eRhCeZtlkzCNCG1JysOzJXGYf5rx80aD1lUgNDU= -github.com/aws/aws-sdk-go-v2/credentials v1.17.38/go.mod h1:TCVYPZeQuLaYNEkf/TVn6k5k/zdVZZ7xH9po548VNNg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4 h1:EoPbZg+DGTRqKKhwk5uDviV9yvx65r1kyoNNC02ZH4Y= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4/go.mod h1:WyLS5qwXHtjKAONYZq/4ewdd+hcVsa3LBu77Ow5uj3k= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.4 h1:ck/Y8XWNR1gHa4BFkwE3oSu7XDJGwl+8TI7E/RB2EcQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.4/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4 h1:4f2/JKYZHAZbQ7koBpZ012bKi32NHPY0m7TDuJgsbug= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.4/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.4 h1:uK6dUUdJtqutK1XO/tmNaQMJiPLCJY/eAeOOmqQ6ygY= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.4/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU= +github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I= +github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 h1:HD6R8K10gPbN9CNqRDOs42QombXlYeLOr4KkIxe2lQs= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8/go.mod h1:x66GdH8qjYTr6Kb4ik38Ewl6moLsg8igbceNsmxVxeA= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= diff --git a/foundry/operator/internal/controller/release_controller.go b/foundry/operator/internal/controller/release_controller.go index 363ba3b7..38f25a83 100644 --- a/foundry/operator/internal/controller/release_controller.go +++ b/foundry/operator/internal/controller/release_controller.go @@ -32,7 +32,7 @@ import ( "github.com/input-output-hk/catalyst-forge/foundry/operator/pkg/handlers" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" depl "github.com/input-output-hk/catalyst-forge/lib/project/deployment/deployer" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" + "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote" ) diff --git a/foundry/operator/internal/controller/suite_env_test.go b/foundry/operator/internal/controller/suite_env_test.go index e64af2be..2941910a 100644 --- a/foundry/operator/internal/controller/suite_env_test.go +++ b/foundry/operator/internal/controller/suite_env_test.go @@ -20,10 +20,10 @@ import ( "github.com/input-output-hk/catalyst-forge/foundry/operator/pkg/handlers" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/deployment/deployer" - "github.com/input-output-hk/catalyst-forge/lib/project/secrets" tu "github.com/input-output-hk/catalyst-forge/lib/project/utils/test" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" + "github.com/input-output-hk/catalyst-forge/lib/secrets" bfs "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote" rm "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote/mocks" From c6e82ade301858ff06b8364fd927922072fd675d Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 17:49:39 -0700 Subject: [PATCH 24/29] chore: change branches to b --- cli/pkg/release/providers/docs.go | 8 ++++---- cli/pkg/release/providers/docs_test.go | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index f40e248b..f8ae5025 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -89,7 +89,7 @@ func (r *DocsReleaser) Release() error { } r.logger.Info("Cleaning existing docs from S3", "bucket", docsConfig.Bucket, "path", s3Path) - if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path, []string{".*/branches/.*"}); err != nil { + if err := r.s3.DeleteDirectory(docsConfig.Bucket, s3Path, []string{".*/b/.*"}); err != nil { return fmt.Errorf("failed to clean existing docs from S3: %w", err) } @@ -111,7 +111,7 @@ func (r *DocsReleaser) Release() error { } if isDefault { - if err := r.cleanupBranches(docsConfig.Bucket, filepath.Join(s3Path, "branches")); err != nil { + if err := r.cleanupBranches(docsConfig.Bucket, filepath.Join(s3Path, "b")); err != nil { return fmt.Errorf("failed to cleanup branches: %w", err) } } @@ -171,7 +171,7 @@ func (r *DocsReleaser) generatePath(projectName string) (string, error) { return s3Path, nil } - return filepath.Join(s3Path, "branches", branch), nil + return filepath.Join(s3Path, "b", branch), nil } // isDefaultBranch returns true if the current branch is the default branch. @@ -214,7 +214,7 @@ func (r *DocsReleaser) postComment(baseURL, name string) error { if branch == r.project.Blueprint.Global.Repo.DefaultBranch { docURL, err = url.JoinPath(baseURL, name) } else { - docURL, err = url.JoinPath(baseURL, name, "branches", branch) + docURL, err = url.JoinPath(baseURL, name, "b", branch) } if err != nil { return fmt.Errorf("failed to join URL path: %w", err) diff --git a/cli/pkg/release/providers/docs_test.go b/cli/pkg/release/providers/docs_test.go index a3697b34..22471ff6 100644 --- a/cli/pkg/release/providers/docs_test.go +++ b/cli/pkg/release/providers/docs_test.go @@ -18,6 +18,8 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/project" "github.com/input-output-hk/catalyst-forge/lib/providers/aws" awsMocks "github.com/input-output-hk/catalyst-forge/lib/providers/aws/mocks" + gh "github.com/input-output-hk/catalyst-forge/lib/providers/github" + ghMocks "github.com/input-output-hk/catalyst-forge/lib/providers/github/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" @@ -189,6 +191,18 @@ func TestDocsReleaserRelease(t *testing.T) { }, } + ghMock := &ghMocks.GithubClientMock{ + ListBranchesFunc: func() ([]gh.Branch, error) { + return nil, nil + }, + ListPullRequestCommentsFunc: func(prNumber int) ([]gh.PullRequestComment, error) { + return nil, nil + }, + PostPullRequestCommentFunc: func(prNumber int, body string) error { + return nil + }, + } + localFs := billy.NewInMemoryFs() for name, content := range tt.files { p := filepath.Join("/", earthly.GetBuildPlatform(), name) @@ -202,6 +216,7 @@ func TestDocsReleaserRelease(t *testing.T) { config: DocsReleaserConfig{Name: tt.releaseName}, force: true, fs: localFs, + ghClient: ghMock, handler: &eventsMocks.EventHandlerMock{FiringFunc: func(_ *project.Project, _ map[string]cue.Value) bool { return true }}, logger: testutils.NewNoopLogger(), project: &tt.project, From 6440bae536121a4b63193ea89d1e0e952fd3c84e Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 18:23:26 -0700 Subject: [PATCH 25/29] wip: testing --- .github/workflows/ci.yml | 163 +++++++------- cli/pkg/release/providers/docs.go | 8 + cli/pkg/release/providers/docs_test.go | 43 +++- lib/providers/aws/s3.go | 2 + lib/providers/github/client.go | 8 +- lib/providers/github/env.go | 53 +++-- lib/providers/github/env_test.go | 10 +- lib/providers/github/mocks/env.go | 285 +++++++++++++++++++++++++ lib/providers/github/mocks/github.go | 6 +- lib/providers/github/opts.go | 2 +- 10 files changed, 461 insertions(+), 119 deletions(-) create mode 100644 lib/providers/github/mocks/env.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b1fe086..1e63ab2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,69 +75,70 @@ jobs: ${{ env.FORGE_REGEX_RELEASE }} ${{ env.FORGE_REGEX_PUBLISH }} ${{ env.FORGE_REGEX_NIGHTLY }} - check: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover] - if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # check: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover] + # if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - build: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check] - if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # build: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check] + # if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - package: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check, build] - if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # package: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check, build] + # if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - test: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check, build, package] - if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # test: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check, build, package] + # if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - nightly: - uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - needs: [discover, check, build, package] - if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true - with: - earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # nightly: + # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + # needs: [discover, check, build, package] + # if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true + # with: + # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} release: uses: input-output-hk/catalyst-forge/.github/workflows/release.yml@master - needs: [discover, check, build, test] + # needs: [discover, check, build, test] + needs: [discover] if: (fromJson(needs.discover.outputs.releases)[0] != null) && !failure() && !cancelled() with: releases: ${{ needs.discover.outputs.releases }} @@ -147,29 +148,29 @@ jobs: secrets: earthly_token: ${{ secrets.earthly_token }} - deploy: - uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master - needs: [discover, check, build, test, release] - if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() - with: - deployments: ${{ needs.discover.outputs.deployments }} - forge_version: ${{ inputs.forge_version }} - local: ${{ inputs.local }} - verbosity: ${{ inputs.verbosity }} - secrets: - earthly_token: ${{ secrets.earthly_token }} + # deploy: + # uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master + # needs: [discover, check, build, test, release] + # if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() + # with: + # deployments: ${{ needs.discover.outputs.deployments }} + # forge_version: ${{ inputs.forge_version }} + # local: ${{ inputs.local }} + # verbosity: ${{ inputs.verbosity }} + # secrets: + # earthly_token: ${{ secrets.earthly_token }} - final: - needs: [check, build, package, test, nightly, release, deploy] - if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} - runs-on: ubuntu-latest - steps: - - name: Final - run: | - if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] - then - echo "Run failed" - exit 1 - else - echo "All done" - fi \ No newline at end of file + # final: + # needs: [check, build, package, test, nightly, release, deploy] + # if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} + # runs-on: ubuntu-latest + # steps: + # - name: Final + # run: | + # if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] + # then + # echo "Run failed" + # exit 1 + # else + # echo "All done" + # fi \ No newline at end of file diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index f8ae5025..859860d2 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -55,6 +55,13 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { + // Testing + branch, err := git.GetBranch(r.project.Repo) + if err != nil { + return fmt.Errorf("failed to get branch: %w", err) + } + r.project.Blueprint.Global.Repo.DefaultBranch = branch + r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) if err := r.run(r.workdir); err != nil { return fmt.Errorf("failed to run docs release target: %w", err) @@ -115,6 +122,7 @@ func (r *DocsReleaser) Release() error { return fmt.Errorf("failed to cleanup branches: %w", err) } } + } r.logger.Info("Docs release complete") diff --git a/cli/pkg/release/providers/docs_test.go b/cli/pkg/release/providers/docs_test.go index 22471ff6..1f9d89f4 100644 --- a/cli/pkg/release/providers/docs_test.go +++ b/cli/pkg/release/providers/docs_test.go @@ -2,7 +2,6 @@ package providers import ( "context" - "fmt" "io" "os" "path/filepath" @@ -32,10 +31,16 @@ import ( ) func TestDocsReleaserRelease(t *testing.T) { + type prPostResult struct { + prNumber int + body string + } + type testResult struct { localFs fs.Filesystem s3Fs fs.Filesystem err error + prPost prPostResult } newProject := func(projectName, branch, bucket, docsPath string) project.Project { @@ -78,20 +83,30 @@ func TestDocsReleaserRelease(t *testing.T) { name string project project.Project releaseName string + prNumber int files map[string]string s3files map[string]string + prComments []gh.PullRequestComment + branches []gh.Branch + inCI bool + isPR bool validate func(*testing.T, testResult) }{ { name: "full", project: newProject("project", "master", "bucket", "prefix"), releaseName: "test", + prNumber: 123, files: map[string]string{ "index.html": "test docs", }, s3files: map[string]string{ "test.html": "test", }, + prComments: []gh.PullRequestComment{}, + branches: []gh.Branch{}, + inCI: true, + isPR: false, validate: func(t *testing.T, result testResult) { assert.NoError(t, result.err) @@ -99,7 +114,6 @@ func TestDocsReleaserRelease(t *testing.T) { if err != nil { return err } - fmt.Println(path) return nil }) @@ -120,6 +134,10 @@ func TestDocsReleaserRelease(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + if tt.inCI { + t.Setenv("GITHUB_ACTIONS", "true") + } + s3Fs := billy.NewInMemoryFs() for name, content := range tt.s3files { p := filepath.Join("/", @@ -128,7 +146,6 @@ func TestDocsReleaserRelease(t *testing.T) { tt.releaseName, name, ) - fmt.Println(p) require.NoError(t, s3Fs.WriteFile(p, []byte(content), 0o644)) } @@ -191,14 +208,29 @@ func TestDocsReleaserRelease(t *testing.T) { }, } + ghEnvMock := &ghMocks.GithubEnvMock{ + IsPRFunc: func() bool { + return tt.isPR + }, + GetPRNumberFunc: func() int { + return tt.prNumber + }, + } + + var prPost prPostResult ghMock := &ghMocks.GithubClientMock{ + EnvFunc: func() gh.GithubEnv { + return ghEnvMock + }, ListBranchesFunc: func() ([]gh.Branch, error) { - return nil, nil + return tt.branches, nil }, ListPullRequestCommentsFunc: func(prNumber int) ([]gh.PullRequestComment, error) { - return nil, nil + return tt.prComments, nil }, PostPullRequestCommentFunc: func(prNumber int, body string) error { + prPost.prNumber = prNumber + prPost.body = body return nil }, } @@ -232,6 +264,7 @@ func TestDocsReleaserRelease(t *testing.T) { localFs: localFs, s3Fs: s3Fs, err: err, + prPost: prPost, }) }) } diff --git a/lib/providers/aws/s3.go b/lib/providers/aws/s3.go index bee8d77e..5e1ecab7 100644 --- a/lib/providers/aws/s3.go +++ b/lib/providers/aws/s3.go @@ -126,6 +126,7 @@ func (c *S3Client) ListImmediateChildren(bucket, prefix string) ([]string, error continue } + fmt.Printf("Common prefix: %s\n", *cp.Prefix) name := strings.TrimSuffix(strings.TrimPrefix(*cp.Prefix, prefix), "/") if name == "" { continue @@ -142,6 +143,7 @@ func (c *S3Client) ListImmediateChildren(bucket, prefix string) ([]string, error input.ContinuationToken = out.NextContinuationToken } + fmt.Printf("Children: %v\n", children) return children, nil } diff --git a/lib/providers/github/client.go b/lib/providers/github/client.go index 4582291e..e8dfa569 100644 --- a/lib/providers/github/client.go +++ b/lib/providers/github/client.go @@ -26,7 +26,7 @@ var ( // GithubClient is the interface for the Github client. type GithubClient interface { CreateRelease(opts *github.RepositoryRelease) (*github.RepositoryRelease, error) - Env() *GithubEnv + Env() GithubEnv GetReleaseByTag(tag string) (*github.RepositoryRelease, error) ListPullRequestComments(prNumber int) ([]PullRequestComment, error) PostPullRequestComment(prNumber int, body string) error @@ -37,7 +37,7 @@ type GithubClient interface { // DefaultGithubClient is the default implementation of the Github client. type DefaultGithubClient struct { client *github.Client - env *GithubEnv + env GithubEnv fs fs.Filesystem logger *slog.Logger opts *DefaultGithubClientOptions @@ -60,7 +60,7 @@ type PullRequestComment struct { } // Env returns the Github environment. -func (g *DefaultGithubClient) Env() *GithubEnv { +func (g *DefaultGithubClient) Env() GithubEnv { return g.env } @@ -259,7 +259,7 @@ func NewDefaultGithubClient(owner, repoName string, opts ...DefaultGithubClientO } if gc.env == nil { - gc.env = &GithubEnv{ + gc.env = &DefaultGithubEnv{ fs: gc.fs, logger: gc.logger, } diff --git a/lib/providers/github/env.go b/lib/providers/github/env.go index 861e358b..63c989e0 100644 --- a/lib/providers/github/env.go +++ b/lib/providers/github/env.go @@ -16,14 +16,27 @@ var ( ErrTagNotFound = fmt.Errorf("tag not found") ) +//go:generate go run github.com/matryer/moq@latest -skip-ensure --pkg mocks -out mocks/env.go . GithubEnv + // GithubEnv provides GitHub environment information. -type GithubEnv struct { +type GithubEnv interface { + GetBranch() string + GetEventPayload() (any, error) + GetEventType() string + GetPRNumber() int + GetTag() string + IsPR() bool + HasEvent() bool +} + +// DefaultGithubEnv provides the default implementation of the GithubEnv interface. +type DefaultGithubEnv struct { fs fs.Filesystem logger *slog.Logger } // GetBranch returns the current branch from the CI environment. -func (g *GithubEnv) GetBranch() string { +func (g *DefaultGithubEnv) GetBranch() string { ref, ok := os.LookupEnv("GITHUB_HEAD_REF") if !ok || ref == "" { if strings.HasPrefix(os.Getenv("GITHUB_REF"), "refs/heads/") { @@ -35,7 +48,7 @@ func (g *GithubEnv) GetBranch() string { } // GetEventPayload returns the GitHub event payload. -func (g *GithubEnv) GetEventPayload() (any, error) { +func (g *DefaultGithubEnv) GetEventPayload() (any, error) { path, pathExists := os.LookupEnv("GITHUB_EVENT_PATH") name, nameExists := os.LookupEnv("GITHUB_EVENT_NAME") @@ -58,13 +71,13 @@ func (g *GithubEnv) GetEventPayload() (any, error) { } // GetEventType returns the GitHub event type. -func (g *GithubEnv) GetEventType() string { +func (g *DefaultGithubEnv) GetEventType() string { return os.Getenv("GITHUB_EVENT_NAME") } // GetTag returns the tag from the CI environment if it exists. // If the tag is not found, an empty string is returned. -func (g *GithubEnv) GetTag() string { +func (g *DefaultGithubEnv) GetTag() string { tag, exists := os.LookupEnv("GITHUB_REF") if exists && strings.HasPrefix(tag, "refs/tags/") { return strings.TrimPrefix(tag, "refs/tags/") @@ -73,22 +86,9 @@ func (g *GithubEnv) GetTag() string { return "" } -// IsPR returns whether the current environment is associated with a pull request. -func (g *GithubEnv) IsPR() bool { - if _, ok := os.LookupEnv("GITHUB_HEAD_REF"); ok { - return true - } - - if g.GetEventType() == "pull_request" { - return true - } - - return false -} - // GetPRNumber returns the pull request number if the current environment is associated with a PR. // Returns 0 if not in a PR context or if the PR number cannot be determined. -func (g *GithubEnv) GetPRNumber() int { +func (g *DefaultGithubEnv) GetPRNumber() int { if !g.IsPR() { return 0 } @@ -116,8 +116,21 @@ func (g *GithubEnv) GetPRNumber() int { return 0 } +// IsPR returns whether the current environment is associated with a pull request. +func (g *DefaultGithubEnv) IsPR() bool { + if _, ok := os.LookupEnv("GITHUB_HEAD_REF"); ok { + return true + } + + if g.GetEventType() == "pull_request" { + return true + } + + return false +} + // HasEvent returns whether a GitHub event payload exists. -func (g *GithubEnv) HasEvent() bool { +func (g *DefaultGithubEnv) HasEvent() bool { _, pathExists := os.LookupEnv("GITHUB_EVENT_PATH") _, nameExists := os.LookupEnv("GITHUB_EVENT_NAME") return pathExists && nameExists diff --git a/lib/providers/github/env_test.go b/lib/providers/github/env_test.go index 9bdfb8ee..ad68c216 100644 --- a/lib/providers/github/env_test.go +++ b/lib/providers/github/env_test.go @@ -44,7 +44,7 @@ func TestGithubEnvGetBranch(t *testing.T) { defer os.Unsetenv(k) } - gh := GithubEnv{} + gh := DefaultGithubEnv{} tt.validate(t, gh.GetBranch()) }) } @@ -121,7 +121,7 @@ func TestGithubEnvGetEventPayload(t *testing.T) { fs := billy.NewInMemoryFs() testutils.SetupFS(t, fs, tt.files) - gh := GithubEnv{ + gh := DefaultGithubEnv{ fs: fs, logger: testutils.NewNoopLogger(), } @@ -133,7 +133,7 @@ func TestGithubEnvGetEventPayload(t *testing.T) { } func TestGithubEnvGetEventType(t *testing.T) { - gh := GithubEnv{} + gh := DefaultGithubEnv{} require.NoError(t, os.Setenv("GITHUB_EVENT_NAME", "push")) assert.Equal(t, "push", gh.GetEventType()) @@ -172,7 +172,7 @@ func TestGithubEnvGetTag(t *testing.T) { defer os.Unsetenv(k) } - gh := GithubEnv{} + gh := DefaultGithubEnv{} tt.validate(t, gh.GetTag()) }) } @@ -215,7 +215,7 @@ func TestGithubEnvHasEvent(t *testing.T) { defer os.Unsetenv(k) } - gh := GithubEnv{} + gh := DefaultGithubEnv{} assert.Equal(t, tt.expect, gh.HasEvent()) }) } diff --git a/lib/providers/github/mocks/env.go b/lib/providers/github/mocks/env.go new file mode 100644 index 00000000..fe24ffc6 --- /dev/null +++ b/lib/providers/github/mocks/env.go @@ -0,0 +1,285 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package mocks + +import ( + "sync" +) + +// GithubEnvMock is a mock implementation of github.GithubEnv. +// +// func TestSomethingThatUsesGithubEnv(t *testing.T) { +// +// // make and configure a mocked github.GithubEnv +// mockedGithubEnv := &GithubEnvMock{ +// GetBranchFunc: func() string { +// panic("mock out the GetBranch method") +// }, +// GetEventPayloadFunc: func() (any, error) { +// panic("mock out the GetEventPayload method") +// }, +// GetEventTypeFunc: func() string { +// panic("mock out the GetEventType method") +// }, +// GetPRNumberFunc: func() int { +// panic("mock out the GetPRNumber method") +// }, +// GetTagFunc: func() string { +// panic("mock out the GetTag method") +// }, +// HasEventFunc: func() bool { +// panic("mock out the HasEvent method") +// }, +// IsPRFunc: func() bool { +// panic("mock out the IsPR method") +// }, +// } +// +// // use mockedGithubEnv in code that requires github.GithubEnv +// // and then make assertions. +// +// } +type GithubEnvMock struct { + // GetBranchFunc mocks the GetBranch method. + GetBranchFunc func() string + + // GetEventPayloadFunc mocks the GetEventPayload method. + GetEventPayloadFunc func() (any, error) + + // GetEventTypeFunc mocks the GetEventType method. + GetEventTypeFunc func() string + + // GetPRNumberFunc mocks the GetPRNumber method. + GetPRNumberFunc func() int + + // GetTagFunc mocks the GetTag method. + GetTagFunc func() string + + // HasEventFunc mocks the HasEvent method. + HasEventFunc func() bool + + // IsPRFunc mocks the IsPR method. + IsPRFunc func() bool + + // calls tracks calls to the methods. + calls struct { + // GetBranch holds details about calls to the GetBranch method. + GetBranch []struct { + } + // GetEventPayload holds details about calls to the GetEventPayload method. + GetEventPayload []struct { + } + // GetEventType holds details about calls to the GetEventType method. + GetEventType []struct { + } + // GetPRNumber holds details about calls to the GetPRNumber method. + GetPRNumber []struct { + } + // GetTag holds details about calls to the GetTag method. + GetTag []struct { + } + // HasEvent holds details about calls to the HasEvent method. + HasEvent []struct { + } + // IsPR holds details about calls to the IsPR method. + IsPR []struct { + } + } + lockGetBranch sync.RWMutex + lockGetEventPayload sync.RWMutex + lockGetEventType sync.RWMutex + lockGetPRNumber sync.RWMutex + lockGetTag sync.RWMutex + lockHasEvent sync.RWMutex + lockIsPR sync.RWMutex +} + +// GetBranch calls GetBranchFunc. +func (mock *GithubEnvMock) GetBranch() string { + if mock.GetBranchFunc == nil { + panic("GithubEnvMock.GetBranchFunc: method is nil but GithubEnv.GetBranch was just called") + } + callInfo := struct { + }{} + mock.lockGetBranch.Lock() + mock.calls.GetBranch = append(mock.calls.GetBranch, callInfo) + mock.lockGetBranch.Unlock() + return mock.GetBranchFunc() +} + +// GetBranchCalls gets all the calls that were made to GetBranch. +// Check the length with: +// +// len(mockedGithubEnv.GetBranchCalls()) +func (mock *GithubEnvMock) GetBranchCalls() []struct { +} { + var calls []struct { + } + mock.lockGetBranch.RLock() + calls = mock.calls.GetBranch + mock.lockGetBranch.RUnlock() + return calls +} + +// GetEventPayload calls GetEventPayloadFunc. +func (mock *GithubEnvMock) GetEventPayload() (any, error) { + if mock.GetEventPayloadFunc == nil { + panic("GithubEnvMock.GetEventPayloadFunc: method is nil but GithubEnv.GetEventPayload was just called") + } + callInfo := struct { + }{} + mock.lockGetEventPayload.Lock() + mock.calls.GetEventPayload = append(mock.calls.GetEventPayload, callInfo) + mock.lockGetEventPayload.Unlock() + return mock.GetEventPayloadFunc() +} + +// GetEventPayloadCalls gets all the calls that were made to GetEventPayload. +// Check the length with: +// +// len(mockedGithubEnv.GetEventPayloadCalls()) +func (mock *GithubEnvMock) GetEventPayloadCalls() []struct { +} { + var calls []struct { + } + mock.lockGetEventPayload.RLock() + calls = mock.calls.GetEventPayload + mock.lockGetEventPayload.RUnlock() + return calls +} + +// GetEventType calls GetEventTypeFunc. +func (mock *GithubEnvMock) GetEventType() string { + if mock.GetEventTypeFunc == nil { + panic("GithubEnvMock.GetEventTypeFunc: method is nil but GithubEnv.GetEventType was just called") + } + callInfo := struct { + }{} + mock.lockGetEventType.Lock() + mock.calls.GetEventType = append(mock.calls.GetEventType, callInfo) + mock.lockGetEventType.Unlock() + return mock.GetEventTypeFunc() +} + +// GetEventTypeCalls gets all the calls that were made to GetEventType. +// Check the length with: +// +// len(mockedGithubEnv.GetEventTypeCalls()) +func (mock *GithubEnvMock) GetEventTypeCalls() []struct { +} { + var calls []struct { + } + mock.lockGetEventType.RLock() + calls = mock.calls.GetEventType + mock.lockGetEventType.RUnlock() + return calls +} + +// GetPRNumber calls GetPRNumberFunc. +func (mock *GithubEnvMock) GetPRNumber() int { + if mock.GetPRNumberFunc == nil { + panic("GithubEnvMock.GetPRNumberFunc: method is nil but GithubEnv.GetPRNumber was just called") + } + callInfo := struct { + }{} + mock.lockGetPRNumber.Lock() + mock.calls.GetPRNumber = append(mock.calls.GetPRNumber, callInfo) + mock.lockGetPRNumber.Unlock() + return mock.GetPRNumberFunc() +} + +// GetPRNumberCalls gets all the calls that were made to GetPRNumber. +// Check the length with: +// +// len(mockedGithubEnv.GetPRNumberCalls()) +func (mock *GithubEnvMock) GetPRNumberCalls() []struct { +} { + var calls []struct { + } + mock.lockGetPRNumber.RLock() + calls = mock.calls.GetPRNumber + mock.lockGetPRNumber.RUnlock() + return calls +} + +// GetTag calls GetTagFunc. +func (mock *GithubEnvMock) GetTag() string { + if mock.GetTagFunc == nil { + panic("GithubEnvMock.GetTagFunc: method is nil but GithubEnv.GetTag was just called") + } + callInfo := struct { + }{} + mock.lockGetTag.Lock() + mock.calls.GetTag = append(mock.calls.GetTag, callInfo) + mock.lockGetTag.Unlock() + return mock.GetTagFunc() +} + +// GetTagCalls gets all the calls that were made to GetTag. +// Check the length with: +// +// len(mockedGithubEnv.GetTagCalls()) +func (mock *GithubEnvMock) GetTagCalls() []struct { +} { + var calls []struct { + } + mock.lockGetTag.RLock() + calls = mock.calls.GetTag + mock.lockGetTag.RUnlock() + return calls +} + +// HasEvent calls HasEventFunc. +func (mock *GithubEnvMock) HasEvent() bool { + if mock.HasEventFunc == nil { + panic("GithubEnvMock.HasEventFunc: method is nil but GithubEnv.HasEvent was just called") + } + callInfo := struct { + }{} + mock.lockHasEvent.Lock() + mock.calls.HasEvent = append(mock.calls.HasEvent, callInfo) + mock.lockHasEvent.Unlock() + return mock.HasEventFunc() +} + +// HasEventCalls gets all the calls that were made to HasEvent. +// Check the length with: +// +// len(mockedGithubEnv.HasEventCalls()) +func (mock *GithubEnvMock) HasEventCalls() []struct { +} { + var calls []struct { + } + mock.lockHasEvent.RLock() + calls = mock.calls.HasEvent + mock.lockHasEvent.RUnlock() + return calls +} + +// IsPR calls IsPRFunc. +func (mock *GithubEnvMock) IsPR() bool { + if mock.IsPRFunc == nil { + panic("GithubEnvMock.IsPRFunc: method is nil but GithubEnv.IsPR was just called") + } + callInfo := struct { + }{} + mock.lockIsPR.Lock() + mock.calls.IsPR = append(mock.calls.IsPR, callInfo) + mock.lockIsPR.Unlock() + return mock.IsPRFunc() +} + +// IsPRCalls gets all the calls that were made to IsPR. +// Check the length with: +// +// len(mockedGithubEnv.IsPRCalls()) +func (mock *GithubEnvMock) IsPRCalls() []struct { +} { + var calls []struct { + } + mock.lockIsPR.RLock() + calls = mock.calls.IsPR + mock.lockIsPR.RUnlock() + return calls +} diff --git a/lib/providers/github/mocks/github.go b/lib/providers/github/mocks/github.go index 0d5e02ea..f460447f 100644 --- a/lib/providers/github/mocks/github.go +++ b/lib/providers/github/mocks/github.go @@ -18,7 +18,7 @@ import ( // CreateReleaseFunc: func(opts *v66github.RepositoryRelease) (*v66github.RepositoryRelease, error) { // panic("mock out the CreateRelease method") // }, -// EnvFunc: func() *providersgithub.GithubEnv { +// EnvFunc: func() providersgithub.GithubEnv { // panic("mock out the Env method") // }, // GetReleaseByTagFunc: func(tag string) (*v66github.RepositoryRelease, error) { @@ -47,7 +47,7 @@ type GithubClientMock struct { CreateReleaseFunc func(opts *v66github.RepositoryRelease) (*v66github.RepositoryRelease, error) // EnvFunc mocks the Env method. - EnvFunc func() *providersgithub.GithubEnv + EnvFunc func() providersgithub.GithubEnv // GetReleaseByTagFunc mocks the GetReleaseByTag method. GetReleaseByTagFunc func(tag string) (*v66github.RepositoryRelease, error) @@ -144,7 +144,7 @@ func (mock *GithubClientMock) CreateReleaseCalls() []struct { } // Env calls EnvFunc. -func (mock *GithubClientMock) Env() *providersgithub.GithubEnv { +func (mock *GithubClientMock) Env() providersgithub.GithubEnv { if mock.EnvFunc == nil { panic("GithubClientMock.EnvFunc: method is nil but GithubClient.Env was just called") } diff --git a/lib/providers/github/opts.go b/lib/providers/github/opts.go index 7b32423c..e994c65a 100644 --- a/lib/providers/github/opts.go +++ b/lib/providers/github/opts.go @@ -47,7 +47,7 @@ func WithFs(fs fs.Filesystem) DefaultGithubClientOption { } // WithGithubEnv sets the Github environment for the Github client. -func WithGithubEnv(env *GithubEnv) DefaultGithubClientOption { +func WithGithubEnv(env GithubEnv) DefaultGithubClientOption { return func(c *DefaultGithubClient) { c.env = env } From 3fd02827878402e13eba2429562b2986a6e9b8c2 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 19:36:27 -0700 Subject: [PATCH 26/29] wip: finishes test --- cli/pkg/events/merge.go | 8 +- cli/pkg/release/providers/docs.go | 13 +- cli/pkg/release/providers/docs_test.go | 204 ++++++++++++++++++++----- lib/project/project/loader.go | 9 +- lib/providers/aws/s3.go | 2 - lib/providers/git/branch.go | 7 +- lib/providers/git/tag.go | 6 +- 7 files changed, 190 insertions(+), 59 deletions(-) diff --git a/cli/pkg/events/merge.go b/cli/pkg/events/merge.go index 35f6ca85..0a3cbed3 100644 --- a/cli/pkg/events/merge.go +++ b/cli/pkg/events/merge.go @@ -7,6 +7,7 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/project" "github.com/input-output-hk/catalyst-forge/lib/providers/git" + "github.com/input-output-hk/catalyst-forge/lib/providers/github" ) // MergeEvent fires when a merge occurs to the default branch. @@ -20,7 +21,12 @@ type MergeEventConfig struct { } func (m *MergeEvent) Firing(p *project.Project, config cue.Value) (bool, error) { - branch, err := git.GetBranch(p.Repo) + gc, err := github.NewDefaultGithubClient("", "") + if err != nil { + return false, fmt.Errorf("failed to create github client: %w", err) + } + + branch, err := git.GetBranch(gc, p.Repo) if err != nil { return false, fmt.Errorf("failed to get branch: %w", err) } diff --git a/cli/pkg/release/providers/docs.go b/cli/pkg/release/providers/docs.go index 859860d2..2e435c29 100644 --- a/cli/pkg/release/providers/docs.go +++ b/cli/pkg/release/providers/docs.go @@ -55,13 +55,6 @@ type DocsReleaser struct { // Release runs the docs release. func (r *DocsReleaser) Release() error { - // Testing - branch, err := git.GetBranch(r.project.Repo) - if err != nil { - return fmt.Errorf("failed to get branch: %w", err) - } - r.project.Blueprint.Global.Repo.DefaultBranch = branch - r.logger.Info("Running docs release target", "project", r.project.Name, "target", r.release.Target, "dir", r.workdir) if err := r.run(r.workdir); err != nil { return fmt.Errorf("failed to run docs release target: %w", err) @@ -170,7 +163,7 @@ func (r *DocsReleaser) generatePath(projectName string) (string, error) { s3Path = filepath.Join(docsConfig.Path, projectName) } - branch, err := git.GetBranch(r.project.Repo) + branch, err := git.GetBranch(r.ghClient, r.project.Repo) if err != nil { return "", fmt.Errorf("failed to get branch: %w", err) } @@ -184,7 +177,7 @@ func (r *DocsReleaser) generatePath(projectName string) (string, error) { // isDefaultBranch returns true if the current branch is the default branch. func (r *DocsReleaser) isDefaultBranch() (bool, error) { - branch, err := git.GetBranch(r.project.Repo) + branch, err := git.GetBranch(r.ghClient, r.project.Repo) if err != nil { return false, fmt.Errorf("failed to get branch: %w", err) } @@ -213,7 +206,7 @@ func (r *DocsReleaser) postComment(baseURL, name string) error { } } - branch, err := git.GetBranch(r.project.Repo) + branch, err := git.GetBranch(r.ghClient, r.project.Repo) if err != nil { return fmt.Errorf("failed to get branch: %w", err) } diff --git a/cli/pkg/release/providers/docs_test.go b/cli/pkg/release/providers/docs_test.go index 1f9d89f4..26820456 100644 --- a/cli/pkg/release/providers/docs_test.go +++ b/cli/pkg/release/providers/docs_test.go @@ -43,12 +43,13 @@ func TestDocsReleaserRelease(t *testing.T) { prPost prPostResult } - newProject := func(projectName, branch, bucket, docsPath string) project.Project { - repo := testutils.NewTestRepo(t) - require.NoError(t, repo.WriteFile("README.md", []byte("hello docs"))) - _, err := repo.Commit("initial commit") - require.NoError(t, err) + type branchFile struct { + branch string + name string + content string + } + newProject := func(projectName, branch, bucket, docsPath string) project.Project { return project.Project{ Name: projectName, Blueprint: sb.Blueprint{ @@ -75,34 +76,50 @@ func TestDocsReleaserRelease(t *testing.T) { }, }, }, - Repo: &repo, + Repo: nil, } } tests := []struct { - name string - project project.Project - releaseName string - prNumber int - files map[string]string - s3files map[string]string - prComments []gh.PullRequestComment - branches []gh.Branch - inCI bool - isPR bool - validate func(*testing.T, testResult) + name string + projectName string + defaultBranch string + bucket string + prefix string + releaseName string + prNumber int + curBranch string + files map[string]string + s3files map[string]string + branchFiles []branchFile + prComments []gh.PullRequestComment + branches []gh.Branch + inCI bool + isPR bool + validate func(*testing.T, testResult) }{ { - name: "full", - project: newProject("project", "master", "bucket", "prefix"), - releaseName: "test", - prNumber: 123, + name: "default branch", + projectName: "project", + defaultBranch: "master", + bucket: "bucket", + prefix: "prefix", + releaseName: "test", + prNumber: 123, + curBranch: "master", files: map[string]string{ "index.html": "test docs", }, s3files: map[string]string{ "test.html": "test", }, + branchFiles: []branchFile{ + { + branch: "mybranch", + name: "index.html", + content: "test docs", + }, + }, prComments: []gh.PullRequestComment{}, branches: []gh.Branch{}, inCI: true, @@ -110,13 +127,6 @@ func TestDocsReleaserRelease(t *testing.T) { validate: func(t *testing.T, result testResult) { assert.NoError(t, result.err) - result.s3Fs.Walk("/", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - return nil - }) - exists, err := result.s3Fs.Exists("/bucket/prefix/test/index.html") require.NoError(t, err) assert.True(t, exists) @@ -125,9 +135,93 @@ func TestDocsReleaserRelease(t *testing.T) { require.NoError(t, err) assert.False(t, exists) + exists, err = result.s3Fs.Exists("/bucket/prefix/test/b/mybranch/index.html") + require.NoError(t, err) + assert.False(t, exists) + content, err := result.s3Fs.ReadFile("/bucket/prefix/test/index.html") require.NoError(t, err) assert.Equal(t, "test docs", string(content)) + + assert.Equal(t, 0, result.prPost.prNumber) + assert.Equal(t, "", result.prPost.body) + }, + }, + { + name: "pr", + projectName: "project", + defaultBranch: "master", + bucket: "bucket", + prefix: "prefix", + releaseName: "test", + prNumber: 123, + curBranch: "mybranch", + files: map[string]string{ + "index.html": "test docs", + }, + s3files: map[string]string{ + "test.html": "test", + }, + prComments: []gh.PullRequestComment{}, + branches: []gh.Branch{}, + inCI: true, + isPR: true, + validate: func(t *testing.T, result testResult) { + assert.NoError(t, result.err) + + exists, err := result.s3Fs.Exists("/bucket/prefix/test/b/mybranch/index.html") + require.NoError(t, err) + assert.True(t, exists) + + exists, err = result.s3Fs.Exists("/bucket/prefix/test/b/mybranch/test.html") + require.NoError(t, err) + assert.False(t, exists) + + content, err := result.s3Fs.ReadFile("/bucket/prefix/test/b/mybranch/index.html") + require.NoError(t, err) + assert.Equal(t, "test docs", string(content)) + + expectedBody := ` + +## 📚 Docs Preview + +The docs for this PR can be previewed at the following URL: + +https://docs.example.com/test/b/mybranch +` + + assert.Equal(t, expectedBody, result.prPost.body) + }, + }, + { + name: "pr comment exists", + projectName: "project", + defaultBranch: "master", + bucket: "bucket", + prefix: "prefix", + releaseName: "test", + prNumber: 123, + curBranch: "mybranch", + files: map[string]string{ + "index.html": "test docs", + }, + s3files: map[string]string{ + "test.html": "test", + }, + prComments: []gh.PullRequestComment{ + { + Author: "github-actions[bot]", + Body: "", + }, + }, + branches: []gh.Branch{}, + inCI: true, + isPR: true, + validate: func(t *testing.T, result testResult) { + assert.NoError(t, result.err) + + assert.Equal(t, 0, result.prPost.prNumber) + assert.Equal(t, "", result.prPost.body) }, }, } @@ -138,17 +232,33 @@ func TestDocsReleaserRelease(t *testing.T) { t.Setenv("GITHUB_ACTIONS", "true") } + prj := newProject(tt.projectName, tt.defaultBranch, tt.bucket, tt.prefix) + s3Fs := billy.NewInMemoryFs() + logger := testutils.NewNoopLogger() for name, content := range tt.s3files { p := filepath.Join("/", - tt.project.Blueprint.Global.Ci.Release.Docs.Bucket, - tt.project.Blueprint.Global.Ci.Release.Docs.Path, + prj.Blueprint.Global.Ci.Release.Docs.Bucket, + prj.Blueprint.Global.Ci.Release.Docs.Path, tt.releaseName, name, ) require.NoError(t, s3Fs.WriteFile(p, []byte(content), 0o644)) } + for _, branchFile := range tt.branchFiles { + p := filepath.Join("/", + prj.Blueprint.Global.Ci.Release.Docs.Bucket, + prj.Blueprint.Global.Ci.Release.Docs.Path, + tt.releaseName, + "b", + branchFile.branch, + branchFile.name, + ) + require.NoError(t, s3Fs.MkdirAll(filepath.Dir(p), 0o755)) + require.NoError(t, s3Fs.WriteFile(p, []byte(branchFile.content), 0o644)) + } + mockAWSS3 := &awsMocks.AWSS3ClientMock{ PutObjectFunc: func(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) { bucket := *params.Bucket @@ -190,6 +300,29 @@ func TestDocsReleaserRelease(t *testing.T) { } bucketDir := "/" + bucket + if params.Delimiter != nil { + var prefixes []s3types.CommonPrefix + + s3Fs.Walk("/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if info.IsDir() { + return nil + } + + p1 := strings.TrimPrefix(path, "/"+tt.bucket+"/") + if strings.HasPrefix(p1, *params.Prefix) { + prefixes = append(prefixes, s3types.CommonPrefix{Prefix: &p1}) + } + return nil + }) + + truncated := false + return &s3.ListObjectsV2Output{CommonPrefixes: prefixes, IsTruncated: &truncated}, nil + } + var contents []s3types.Object _ = s3Fs.Walk(bucketDir, func(path string, info os.FileInfo, err error) error { if err != nil { @@ -212,6 +345,9 @@ func TestDocsReleaserRelease(t *testing.T) { IsPRFunc: func() bool { return tt.isPR }, + GetBranchFunc: func() string { + return tt.curBranch + }, GetPRNumberFunc: func() int { return tt.prNumber }, @@ -242,16 +378,16 @@ func TestDocsReleaserRelease(t *testing.T) { require.NoError(t, localFs.WriteFile(p, []byte(content), 0o644)) } - w := walker.NewCustomDefaultFSWalker(localFs, testutils.NewNoopLogger()) - s3Client := aws.NewCustomS3Client(mockAWSS3, &w, testutils.NewNoopLogger()) + w := walker.NewCustomDefaultFSWalker(localFs, logger) + s3Client := aws.NewCustomS3Client(mockAWSS3, &w, logger) releaser := &DocsReleaser{ config: DocsReleaserConfig{Name: tt.releaseName}, force: true, fs: localFs, ghClient: ghMock, handler: &eventsMocks.EventHandlerMock{FiringFunc: func(_ *project.Project, _ map[string]cue.Value) bool { return true }}, - logger: testutils.NewNoopLogger(), - project: &tt.project, + logger: logger, + project: &prj, release: sp.Release{Target: "docs"}, releaseName: "docs", runner: &earthlyMocks.ProjectRunnerMock{RunTargetFunc: func(string, ...earthly.EarthlyExecutorOption) error { return nil }}, diff --git a/lib/project/project/loader.go b/lib/project/project/loader.go index feb6c608..98ef9c3d 100644 --- a/lib/project/project/loader.go +++ b/lib/project/project/loader.go @@ -12,6 +12,7 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/blueprint" "github.com/input-output-hk/catalyst-forge/lib/project/injector" "github.com/input-output-hk/catalyst-forge/lib/providers/git" + "github.com/input-output-hk/catalyst-forge/lib/providers/github" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/earthly" @@ -142,7 +143,13 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) { p.logger.Info("Loading tag data") var tag *ProjectTag - gitTag, err := git.GetTag(&repo) + + gc, err := github.NewDefaultGithubClient("", "") + if err != nil { + return Project{}, fmt.Errorf("failed to create github client: %w", err) + } + + gitTag, err := git.GetTag(gc, &repo) if err != nil { p.logger.Warn("Failed to get git tag", "error", err) } else if gitTag != "" { diff --git a/lib/providers/aws/s3.go b/lib/providers/aws/s3.go index 5e1ecab7..bee8d77e 100644 --- a/lib/providers/aws/s3.go +++ b/lib/providers/aws/s3.go @@ -126,7 +126,6 @@ func (c *S3Client) ListImmediateChildren(bucket, prefix string) ([]string, error continue } - fmt.Printf("Common prefix: %s\n", *cp.Prefix) name := strings.TrimSuffix(strings.TrimPrefix(*cp.Prefix, prefix), "/") if name == "" { continue @@ -143,7 +142,6 @@ func (c *S3Client) ListImmediateChildren(bucket, prefix string) ([]string, error input.ContinuationToken = out.NextContinuationToken } - fmt.Printf("Children: %v\n", children) return children, nil } diff --git a/lib/providers/git/branch.go b/lib/providers/git/branch.go index f820d6e2..8c3e84b7 100644 --- a/lib/providers/git/branch.go +++ b/lib/providers/git/branch.go @@ -11,12 +11,7 @@ var ( ErrBranchNotFound = fmt.Errorf("branch not found") ) -func GetBranch(repo *repo.GitRepo) (string, error) { - gc, err := github.NewDefaultGithubClient("", "") - if err != nil { - return "", fmt.Errorf("failed to create github client: %w", err) - } - +func GetBranch(gc github.GithubClient, repo *repo.GitRepo) (string, error) { if github.InCI() { ref := gc.Env().GetBranch() if ref != "" { diff --git a/lib/providers/git/tag.go b/lib/providers/git/tag.go index ff437bd0..5fab4f00 100644 --- a/lib/providers/git/tag.go +++ b/lib/providers/git/tag.go @@ -12,13 +12,9 @@ var ( ) // GetTag returns the tag of the current HEAD commit. -func GetTag(r *repo.GitRepo) (string, error) { +func GetTag(gc github.GithubClient, r *repo.GitRepo) (string, error) { var tag string var err error - gc, err := github.NewDefaultGithubClient("", "") - if err != nil { - return "", fmt.Errorf("failed to create github client: %w", err) - } if github.InCI() { tag = gc.Env().GetTag() From 60f3ab9c3e82f191e96f20359695accb73a66c90 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 19:38:13 -0700 Subject: [PATCH 27/29] wip: cleanup --- .github/workflows/ci.yml | 163 +++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 82 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e63ab2a..1b1fe086 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,70 +75,69 @@ jobs: ${{ env.FORGE_REGEX_RELEASE }} ${{ env.FORGE_REGEX_PUBLISH }} ${{ env.FORGE_REGEX_NIGHTLY }} - # check: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover] - # if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + check: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover] + if: (fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^check(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # build: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check] - # if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + build: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check] + if: (fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^build(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # package: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check, build] - # if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + package: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check, build] + if: (fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^package(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # test: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check, build, package] - # if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + test: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check, build, package] + if: (fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$'] != null) && !failure() && !cancelled() + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^test(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # nightly: - # uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master - # needs: [discover, check, build, package] - # if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true - # with: - # earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + nightly: + uses: input-output-hk/catalyst-forge/.github/workflows/run.yml@master + needs: [discover, check, build, package] + if: (fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$'] != null) && !failure() && !cancelled() && inputs.nightly == true + with: + earthfiles: ${{ toJson(fromJson(needs.discover.outputs.earthfiles)['^nightly(-.*)?$']) }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} release: uses: input-output-hk/catalyst-forge/.github/workflows/release.yml@master - # needs: [discover, check, build, test] - needs: [discover] + needs: [discover, check, build, test] if: (fromJson(needs.discover.outputs.releases)[0] != null) && !failure() && !cancelled() with: releases: ${{ needs.discover.outputs.releases }} @@ -148,29 +147,29 @@ jobs: secrets: earthly_token: ${{ secrets.earthly_token }} - # deploy: - # uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master - # needs: [discover, check, build, test, release] - # if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() - # with: - # deployments: ${{ needs.discover.outputs.deployments }} - # forge_version: ${{ inputs.forge_version }} - # local: ${{ inputs.local }} - # verbosity: ${{ inputs.verbosity }} - # secrets: - # earthly_token: ${{ secrets.earthly_token }} + deploy: + uses: input-output-hk/catalyst-forge/.github/workflows/deploy.yml@master + needs: [discover, check, build, test, release] + if: (fromJson(needs.discover.outputs.deployments)[0] != null) && !failure() && !cancelled() + with: + deployments: ${{ needs.discover.outputs.deployments }} + forge_version: ${{ inputs.forge_version }} + local: ${{ inputs.local }} + verbosity: ${{ inputs.verbosity }} + secrets: + earthly_token: ${{ secrets.earthly_token }} - # final: - # needs: [check, build, package, test, nightly, release, deploy] - # if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} - # runs-on: ubuntu-latest - # steps: - # - name: Final - # run: | - # if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] - # then - # echo "Run failed" - # exit 1 - # else - # echo "All done" - # fi \ No newline at end of file + final: + needs: [check, build, package, test, nightly, release, deploy] + if: ${{ always() && (contains(needs.*.result, 'failure') || !failure() && !cancelled()) }} + runs-on: ubuntu-latest + steps: + - name: Final + run: | + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] + then + echo "Run failed" + exit 1 + else + echo "All done" + fi \ No newline at end of file From 7e88671f63e35000af6534292067c55c6783c639 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 19:48:48 -0700 Subject: [PATCH 28/29] wip: refactor secrets into providers --- cli/Earthfile | 1 - cli/cmd/cmds/secret.go | 2 +- cli/cmd/main.go | 2 +- cli/go.mod | 9 +- cli/pkg/earthly/earthly.go | 2 +- cli/pkg/earthly/earthly_test.go | 4 +- cli/pkg/earthly/project.go | 2 +- cli/pkg/earthly/project_test.go | 4 +- cli/pkg/earthly/satellite/satellite.go | 2 +- cli/pkg/earthly/satellite/satellite_test.go | 4 +- cli/pkg/events/tag_test.go | 2 +- cli/pkg/run/context.go | 2 +- cli/tui/ci/ci.go | 2 +- foundry/operator/cmd/main.go | 2 +- foundry/operator/go.mod | 3 +- .../internal/controller/release_controller.go | 2 +- .../internal/controller/suite_env_test.go | 2 +- lib/project/Earthfile | 1 - lib/project/deployment/deployer/deployer.go | 2 +- lib/project/deployment/module.go | 2 +- lib/project/deployment/module_test.go | 4 +- lib/project/go.mod | 3 - lib/project/project/loader.go | 2 +- lib/project/project/project.go | 2 +- lib/project/utils/test/secrets.go | 4 +- lib/providers/Earthfile | 1 - lib/providers/earthly/earthly.go | 2 +- lib/providers/git/git.go | 2 +- lib/providers/github/client.go | 2 +- lib/providers/github/creds.go | 2 +- lib/providers/github/opts.go | 2 +- lib/providers/go.mod | 5 +- lib/{ => providers}/secrets/client.go | 2 +- lib/{ => providers}/secrets/interface.go | 0 .../secrets/mocks/interface_mock.go | 2 +- lib/{ => providers}/secrets/providers.go | 0 lib/{ => providers}/secrets/providers/aws.go | 0 .../secrets/providers/aws_mock_test.go | 0 .../secrets/providers/aws_test.go | 0 lib/{ => providers}/secrets/providers/env.go | 0 .../secrets/providers/env_test.go | 0 .../secrets/providers/local.go | 0 .../secrets/providers/local_test.go | 0 lib/{ => providers}/secrets/secrets.go | 0 lib/secrets/.earthlyignore | 4 - lib/secrets/Earthfile | 39 ---- lib/secrets/LICENSE-APACHE | 201 ------------------ lib/secrets/LICENSE-MIT | 25 --- lib/secrets/blueprint.cue | 1 - lib/secrets/go.mod | 57 ----- lib/secrets/go.sum | 175 --------------- lib/tools/go.mod | 2 - 52 files changed, 37 insertions(+), 554 deletions(-) rename lib/{ => providers}/secrets/client.go (94%) rename lib/{ => providers}/secrets/interface.go (100%) rename lib/{ => providers}/secrets/mocks/interface_mock.go (97%) rename lib/{ => providers}/secrets/providers.go (100%) rename lib/{ => providers}/secrets/providers/aws.go (100%) rename lib/{ => providers}/secrets/providers/aws_mock_test.go (100%) rename lib/{ => providers}/secrets/providers/aws_test.go (100%) rename lib/{ => providers}/secrets/providers/env.go (100%) rename lib/{ => providers}/secrets/providers/env_test.go (100%) rename lib/{ => providers}/secrets/providers/local.go (100%) rename lib/{ => providers}/secrets/providers/local_test.go (100%) rename lib/{ => providers}/secrets/secrets.go (100%) delete mode 100644 lib/secrets/.earthlyignore delete mode 100644 lib/secrets/Earthfile delete mode 100644 lib/secrets/LICENSE-APACHE delete mode 100644 lib/secrets/LICENSE-MIT delete mode 100644 lib/secrets/blueprint.cue delete mode 100644 lib/secrets/go.mod delete mode 100644 lib/secrets/go.sum diff --git a/cli/Earthfile b/cli/Earthfile index 74de4452..58d7b59b 100644 --- a/cli/Earthfile +++ b/cli/Earthfile @@ -15,7 +15,6 @@ deps: COPY ../lib/project+src/src /lib/project COPY ../lib/providers+src/src /lib/providers COPY ../lib/schema+src/src /lib/schema - COPY ../lib/secrets+src/src /lib/secrets COPY ../lib/tools+src/src /lib/tools COPY go.mod go.sum . diff --git a/cli/cmd/cmds/secret.go b/cli/cmd/cmds/secret.go index 70a2aec9..53ab405d 100644 --- a/cli/cmd/cmds/secret.go +++ b/cli/cmd/cmds/secret.go @@ -7,8 +7,8 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/cli/pkg/utils" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" ) diff --git a/cli/cmd/main.go b/cli/cmd/main.go index 9f2ac24d..625f790f 100644 --- a/cli/cmd/main.go +++ b/cli/cmd/main.go @@ -14,8 +14,8 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" schema "github.com/input-output-hk/catalyst-forge/lib/schema" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" "github.com/posener/complete" "github.com/willabides/kongplete" diff --git a/cli/go.mod b/cli/go.mod index e3a0cb10..e0efeb3b 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -5,9 +5,6 @@ go 1.24.2 require ( cuelang.org/go v0.12.0 github.com/alecthomas/kong v0.9.0 - github.com/aws/aws-sdk-go v1.55.7 - github.com/aws/aws-sdk-go-v2 v1.36.6 - github.com/aws/aws-sdk-go-v2/config v1.29.18 github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1 github.com/charmbracelet/bubbles v0.20.0 @@ -18,7 +15,6 @@ require ( github.com/input-output-hk/catalyst-forge/lib/project v0.0.0 github.com/input-output-hk/catalyst-forge/lib/providers v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 - github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 github.com/posener/complete v1.2.3 github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a @@ -48,7 +44,10 @@ require ( github.com/adrg/xdg v0.5.3 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230219212500-1f9a474cc2dc // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.6 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.18 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect @@ -277,6 +276,4 @@ replace github.com/input-output-hk/catalyst-forge/lib/providers => ../lib/provid replace github.com/input-output-hk/catalyst-forge/lib/schema => ../lib/schema -replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../lib/secrets - replace github.com/input-output-hk/catalyst-forge/lib/tools => ../lib/tools diff --git a/cli/pkg/earthly/earthly.go b/cli/pkg/earthly/earthly.go index 52b69716..4fbb0785 100644 --- a/cli/pkg/earthly/earthly.go +++ b/cli/pkg/earthly/earthly.go @@ -10,8 +10,8 @@ import ( "strings" "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" + secretstore "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - secretstore "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // EarthlyExecutorOption is an option for configuring an EarthlyExecutor. diff --git a/cli/pkg/earthly/earthly_test.go b/cli/pkg/earthly/earthly_test.go index 4462b33a..f4e45221 100644 --- a/cli/pkg/earthly/earthly_test.go +++ b/cli/pkg/earthly/earthly_test.go @@ -6,9 +6,9 @@ import ( "testing" emocks "github.com/input-output-hk/catalyst-forge/cli/pkg/executor/mocks" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" + smocks "github.com/input-output-hk/catalyst-forge/lib/providers/secrets/mocks" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" - smocks "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" "github.com/stretchr/testify/assert" ) diff --git a/cli/pkg/earthly/project.go b/cli/pkg/earthly/project.go index faff287b..c1685523 100644 --- a/cli/pkg/earthly/project.go +++ b/cli/pkg/earthly/project.go @@ -10,9 +10,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/executor" "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" - "github.com/input-output-hk/catalyst-forge/lib/secrets" ) var ( diff --git a/cli/pkg/earthly/project_test.go b/cli/pkg/earthly/project_test.go index c70fbfc7..c089871f 100644 --- a/cli/pkg/earthly/project_test.go +++ b/cli/pkg/earthly/project_test.go @@ -10,9 +10,9 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/lib/project/blueprint" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" + smocks "github.com/input-output-hk/catalyst-forge/lib/providers/secrets/mocks" schema "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" - "github.com/input-output-hk/catalyst-forge/lib/secrets" - smocks "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/cli/pkg/earthly/satellite/satellite.go b/cli/pkg/earthly/satellite/satellite.go index 0ca55463..8896388a 100644 --- a/cli/pkg/earthly/satellite/satellite.go +++ b/cli/pkg/earthly/satellite/satellite.go @@ -8,7 +8,7 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/project" "github.com/input-output-hk/catalyst-forge/lib/providers/earthly" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "gopkg.in/yaml.v3" diff --git a/cli/pkg/earthly/satellite/satellite_test.go b/cli/pkg/earthly/satellite/satellite_test.go index dceeb6f4..3450e910 100644 --- a/cli/pkg/earthly/satellite/satellite_test.go +++ b/cli/pkg/earthly/satellite/satellite_test.go @@ -8,12 +8,12 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/internal/testutils" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" + smocks "github.com/input-output-hk/catalyst-forge/lib/providers/secrets/mocks" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" sg "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/global/providers" - "github.com/input-output-hk/catalyst-forge/lib/secrets" - smocks "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/stretchr/testify/require" diff --git a/cli/pkg/events/tag_test.go b/cli/pkg/events/tag_test.go index b201026a..5a436e07 100644 --- a/cli/pkg/events/tag_test.go +++ b/cli/pkg/events/tag_test.go @@ -5,8 +5,8 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" schema "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" "github.com/stretchr/testify/assert" ) diff --git a/cli/pkg/run/context.go b/cli/pkg/run/context.go index 19cd6d32..f633df46 100644 --- a/cli/pkg/run/context.go +++ b/cli/pkg/run/context.go @@ -6,7 +6,7 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/cli/tui/ci/ci.go b/cli/tui/ci/ci.go index 59adbb13..cd7ab9df 100644 --- a/cli/tui/ci/ci.go +++ b/cli/tui/ci/ci.go @@ -16,7 +16,7 @@ import ( "github.com/input-output-hk/catalyst-forge/cli/pkg/run" "github.com/input-output-hk/catalyst-forge/cli/pkg/scan" "github.com/input-output-hk/catalyst-forge/lib/project/project" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/walker" ) diff --git a/foundry/operator/cmd/main.go b/foundry/operator/cmd/main.go index 259f5e62..6eabce77 100644 --- a/foundry/operator/cmd/main.go +++ b/foundry/operator/cmd/main.go @@ -48,7 +48,7 @@ import ( "github.com/input-output-hk/catalyst-forge/foundry/operator/pkg/handlers" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/providers/git" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote" // +kubebuilder:scaffold:imports diff --git a/foundry/operator/go.mod b/foundry/operator/go.mod index 0a781051..636e9d4a 100644 --- a/foundry/operator/go.mod +++ b/foundry/operator/go.mod @@ -13,7 +13,6 @@ require ( github.com/input-output-hk/catalyst-forge/lib/project v0.0.0 github.com/input-output-hk/catalyst-forge/lib/providers v0.0.0 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 - github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 @@ -278,7 +277,7 @@ replace github.com/input-output-hk/catalyst-forge/lib/providers => ../../lib/pro replace github.com/input-output-hk/catalyst-forge/lib/schema => ../../lib/schema -replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../../lib/secrets +replace github.com/input-output-hk/catalyst-forge/lib/provider/secrets => ../../lib/secrets replace github.com/input-output-hk/catalyst-forge/lib/tools => ../../lib/tools diff --git a/foundry/operator/internal/controller/release_controller.go b/foundry/operator/internal/controller/release_controller.go index 38f25a83..03037265 100644 --- a/foundry/operator/internal/controller/release_controller.go +++ b/foundry/operator/internal/controller/release_controller.go @@ -32,7 +32,7 @@ import ( "github.com/input-output-hk/catalyst-forge/foundry/operator/pkg/handlers" "github.com/input-output-hk/catalyst-forge/lib/project/deployment" depl "github.com/input-output-hk/catalyst-forge/lib/project/deployment/deployer" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote" ) diff --git a/foundry/operator/internal/controller/suite_env_test.go b/foundry/operator/internal/controller/suite_env_test.go index 2941910a..b24c6904 100644 --- a/foundry/operator/internal/controller/suite_env_test.go +++ b/foundry/operator/internal/controller/suite_env_test.go @@ -21,9 +21,9 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/deployment" "github.com/input-output-hk/catalyst-forge/lib/project/deployment/deployer" tu "github.com/input-output-hk/catalyst-forge/lib/project/utils/test" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" sc "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" bfs "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote" rm "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo/remote/mocks" diff --git a/lib/project/Earthfile b/lib/project/Earthfile index 4e7aa497..9d79fac6 100644 --- a/lib/project/Earthfile +++ b/lib/project/Earthfile @@ -12,7 +12,6 @@ deps: COPY ../providers+src/src /providers COPY ../schema+src/src /schema - COPY ../secrets+src/src /secrets COPY ../tools+src/src /tools COPY go.mod go.sum . diff --git a/lib/project/deployment/deployer/deployer.go b/lib/project/deployment/deployer/deployer.go index 69b0ac34..8b3c34b9 100644 --- a/lib/project/deployment/deployer/deployer.go +++ b/lib/project/deployment/deployer/deployer.go @@ -11,8 +11,8 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/deployment/generator" "github.com/input-output-hk/catalyst-forge/lib/project/project" "github.com/input-output-hk/catalyst-forge/lib/providers/git" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" diff --git a/lib/project/deployment/module.go b/lib/project/deployment/module.go index f77d03a2..ac36e0f4 100644 --- a/lib/project/deployment/module.go +++ b/lib/project/deployment/module.go @@ -8,8 +8,8 @@ import ( "cuelang.org/go/cue/cuecontext" "cuelang.org/go/cue/format" "github.com/input-output-hk/catalyst-forge/lib/project/project" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) diff --git a/lib/project/deployment/module_test.go b/lib/project/deployment/module_test.go index 76a7ca0c..8f676d21 100644 --- a/lib/project/deployment/module_test.go +++ b/lib/project/deployment/module_test.go @@ -5,9 +5,9 @@ import ( "testing" "cuelang.org/go/cue/cuecontext" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" + sm "github.com/input-output-hk/catalyst-forge/lib/providers/secrets/mocks" sp "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/project" - "github.com/input-output-hk/catalyst-forge/lib/secrets" - sm "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" "github.com/input-output-hk/catalyst-forge/lib/tools/testutils" diff --git a/lib/project/go.mod b/lib/project/go.mod index e4b95a27..f72f6511 100644 --- a/lib/project/go.mod +++ b/lib/project/go.mod @@ -8,7 +8,6 @@ require ( github.com/google/go-github/v66 v66.0.0 github.com/input-output-hk/catalyst-forge/lib/providers v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 - github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 github.com/stretchr/testify v1.10.0 helm.sh/helm/v3 v3.17.0 @@ -247,8 +246,6 @@ replace github.com/input-output-hk/catalyst-forge/lib/providers => ../providers replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema -replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../secrets - replace github.com/input-output-hk/catalyst-forge/lib/tools => ../tools go 1.24.2 diff --git a/lib/project/project/loader.go b/lib/project/project/loader.go index 98ef9c3d..c667db26 100644 --- a/lib/project/project/loader.go +++ b/lib/project/project/loader.go @@ -13,8 +13,8 @@ import ( "github.com/input-output-hk/catalyst-forge/lib/project/injector" "github.com/input-output-hk/catalyst-forge/lib/providers/git" "github.com/input-output-hk/catalyst-forge/lib/providers/github" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/earthly" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" diff --git a/lib/project/project/project.go b/lib/project/project/project.go index 234ce8ec..e0cefff4 100644 --- a/lib/project/project/project.go +++ b/lib/project/project/project.go @@ -8,8 +8,8 @@ import ( "cuelang.org/go/cue" "github.com/input-output-hk/catalyst-forge/lib/project/blueprint" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" sb "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/earthly" "github.com/input-output-hk/catalyst-forge/lib/tools/git/repo" ) diff --git a/lib/project/utils/test/secrets.go b/lib/project/utils/test/secrets.go index 296db8de..b1940b03 100644 --- a/lib/project/utils/test/secrets.go +++ b/lib/project/utils/test/secrets.go @@ -4,8 +4,8 @@ import ( "encoding/json" "log/slog" - "github.com/input-output-hk/catalyst-forge/lib/secrets" - sm "github.com/input-output-hk/catalyst-forge/lib/secrets/mocks" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" + sm "github.com/input-output-hk/catalyst-forge/lib/providers/secrets/mocks" ) func NewMockSecretStore(result map[string]string) secrets.SecretStore { diff --git a/lib/providers/Earthfile b/lib/providers/Earthfile index db81f18a..d43e1619 100644 --- a/lib/providers/Earthfile +++ b/lib/providers/Earthfile @@ -11,7 +11,6 @@ deps: CACHE --persist --sharing shared /go COPY ../schema+src/src /schema - COPY ../secrets+src/src /secrets COPY ../tools+src/src /tools COPY go.mod go.sum . diff --git a/lib/providers/earthly/earthly.go b/lib/providers/earthly/earthly.go index 7486866b..1bd39297 100644 --- a/lib/providers/earthly/earthly.go +++ b/lib/providers/earthly/earthly.go @@ -4,8 +4,8 @@ import ( "fmt" "log/slog" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // EarthlyProviderCreds is the struct that holds the credentials for the Earthly provider. diff --git a/lib/providers/git/git.go b/lib/providers/git/git.go index 70e3f3bf..3891e6d0 100644 --- a/lib/providers/git/git.go +++ b/lib/providers/git/git.go @@ -4,8 +4,8 @@ import ( "fmt" "log/slog" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // GitProviderCreds is the struct that holds the credentials for the Git provider diff --git a/lib/providers/github/client.go b/lib/providers/github/client.go index e8dfa569..c27b3973 100644 --- a/lib/providers/github/client.go +++ b/lib/providers/github/client.go @@ -9,7 +9,7 @@ import ( "path/filepath" "github.com/google/go-github/v66/github" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" "github.com/input-output-hk/catalyst-forge/lib/tools/fs/billy" ) diff --git a/lib/providers/github/creds.go b/lib/providers/github/creds.go index 74ba68bf..7e9848d4 100644 --- a/lib/providers/github/creds.go +++ b/lib/providers/github/creds.go @@ -4,8 +4,8 @@ import ( "fmt" "log/slog" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" ) // GithubProviderCreds is the struct that holds the credentials for the Github provider diff --git a/lib/providers/github/opts.go b/lib/providers/github/opts.go index e994c65a..2d4cc599 100644 --- a/lib/providers/github/opts.go +++ b/lib/providers/github/opts.go @@ -5,8 +5,8 @@ import ( "os" "github.com/google/go-github/v66/github" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" "github.com/input-output-hk/catalyst-forge/lib/schema/blueprint/common" - "github.com/input-output-hk/catalyst-forge/lib/secrets" "github.com/input-output-hk/catalyst-forge/lib/tools/fs" ) diff --git a/lib/providers/go.mod b/lib/providers/go.mod index 8a372dfb..ea3d532c 100644 --- a/lib/providers/go.mod +++ b/lib/providers/go.mod @@ -4,8 +4,6 @@ go 1.24.2 replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema -replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../secrets - replace github.com/input-output-hk/catalyst-forge/lib/tools => ../tools require ( @@ -14,9 +12,9 @@ require ( github.com/aws/aws-sdk-go-v2/config v1.29.18 github.com/aws/aws-sdk-go-v2/service/ecr v1.46.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.84.1 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 github.com/google/go-github/v66 v66.0.0 github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 - github.com/input-output-hk/catalyst-forge/lib/secrets v0.0.0-00010101000000-000000000000 github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 github.com/stretchr/testify v1.10.0 ) @@ -37,7 +35,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.5 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.18 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect diff --git a/lib/secrets/client.go b/lib/providers/secrets/client.go similarity index 94% rename from lib/secrets/client.go rename to lib/providers/secrets/client.go index f50d0f9e..1a0ccd35 100644 --- a/lib/secrets/client.go +++ b/lib/providers/secrets/client.go @@ -4,7 +4,7 @@ import ( "fmt" "log/slog" - "github.com/input-output-hk/catalyst-forge/lib/secrets/providers" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets/providers" ) // SecretStore is a store of secret providers. diff --git a/lib/secrets/interface.go b/lib/providers/secrets/interface.go similarity index 100% rename from lib/secrets/interface.go rename to lib/providers/secrets/interface.go diff --git a/lib/secrets/mocks/interface_mock.go b/lib/providers/secrets/mocks/interface_mock.go similarity index 97% rename from lib/secrets/mocks/interface_mock.go rename to lib/providers/secrets/mocks/interface_mock.go index ad2c244c..b028a38e 100644 --- a/lib/secrets/mocks/interface_mock.go +++ b/lib/providers/secrets/mocks/interface_mock.go @@ -6,7 +6,7 @@ package mocks import ( "sync" - "github.com/input-output-hk/catalyst-forge/lib/secrets" + "github.com/input-output-hk/catalyst-forge/lib/providers/secrets" ) // Ensure, that SecretProviderMock does implement secrets.SecretProvider. diff --git a/lib/secrets/providers.go b/lib/providers/secrets/providers.go similarity index 100% rename from lib/secrets/providers.go rename to lib/providers/secrets/providers.go diff --git a/lib/secrets/providers/aws.go b/lib/providers/secrets/providers/aws.go similarity index 100% rename from lib/secrets/providers/aws.go rename to lib/providers/secrets/providers/aws.go diff --git a/lib/secrets/providers/aws_mock_test.go b/lib/providers/secrets/providers/aws_mock_test.go similarity index 100% rename from lib/secrets/providers/aws_mock_test.go rename to lib/providers/secrets/providers/aws_mock_test.go diff --git a/lib/secrets/providers/aws_test.go b/lib/providers/secrets/providers/aws_test.go similarity index 100% rename from lib/secrets/providers/aws_test.go rename to lib/providers/secrets/providers/aws_test.go diff --git a/lib/secrets/providers/env.go b/lib/providers/secrets/providers/env.go similarity index 100% rename from lib/secrets/providers/env.go rename to lib/providers/secrets/providers/env.go diff --git a/lib/secrets/providers/env_test.go b/lib/providers/secrets/providers/env_test.go similarity index 100% rename from lib/secrets/providers/env_test.go rename to lib/providers/secrets/providers/env_test.go diff --git a/lib/secrets/providers/local.go b/lib/providers/secrets/providers/local.go similarity index 100% rename from lib/secrets/providers/local.go rename to lib/providers/secrets/providers/local.go diff --git a/lib/secrets/providers/local_test.go b/lib/providers/secrets/providers/local_test.go similarity index 100% rename from lib/secrets/providers/local_test.go rename to lib/providers/secrets/providers/local_test.go diff --git a/lib/secrets/secrets.go b/lib/providers/secrets/secrets.go similarity index 100% rename from lib/secrets/secrets.go rename to lib/providers/secrets/secrets.go diff --git a/lib/secrets/.earthlyignore b/lib/secrets/.earthlyignore deleted file mode 100644 index 3d720b45..00000000 --- a/lib/secrets/.earthlyignore +++ /dev/null @@ -1,4 +0,0 @@ -Earthfile -README.md -LICENSE-* -blueprint.cue \ No newline at end of file diff --git a/lib/secrets/Earthfile b/lib/secrets/Earthfile deleted file mode 100644 index d43e1619..00000000 --- a/lib/secrets/Earthfile +++ /dev/null @@ -1,39 +0,0 @@ -VERSION 0.8 - -deps: - FROM golang:1.24.2-bookworm - - WORKDIR /work - - RUN mkdir -p /go/cache && mkdir -p /go/modcache - ENV GOCACHE=/go/cache - ENV GOMODCACHE=/go/modcache - CACHE --persist --sharing shared /go - - COPY ../schema+src/src /schema - COPY ../tools+src/src /tools - - COPY go.mod go.sum . - RUN go mod download - -src: - FROM +deps - - CACHE --persist --sharing shared /go - - COPY . . - - RUN go generate ./... - - SAVE ARTIFACT . src - -check: - FROM +src - - RUN gofmt -l . | grep . && exit 1 || exit 0 - RUN go vet ./... - -test: - FROM +src - - RUN go test ./... \ No newline at end of file diff --git a/lib/secrets/LICENSE-APACHE b/lib/secrets/LICENSE-APACHE deleted file mode 100644 index a55761ab..00000000 --- a/lib/secrets/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright (c) 2023 Input Output (IOG). - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file diff --git a/lib/secrets/LICENSE-MIT b/lib/secrets/LICENSE-MIT deleted file mode 100644 index ac4df9c0..00000000 --- a/lib/secrets/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2024 Input Output (IOG). - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/secrets/blueprint.cue b/lib/secrets/blueprint.cue deleted file mode 100644 index acd6ce1b..00000000 --- a/lib/secrets/blueprint.cue +++ /dev/null @@ -1 +0,0 @@ -project: name: "blueprint" diff --git a/lib/secrets/go.mod b/lib/secrets/go.mod deleted file mode 100644 index 8cad7d66..00000000 --- a/lib/secrets/go.mod +++ /dev/null @@ -1,57 +0,0 @@ -module github.com/input-output-hk/catalyst-forge/lib/secrets - -go 1.24.2 - -replace github.com/input-output-hk/catalyst-forge/lib/providers => ../providers - -replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema - -replace github.com/input-output-hk/catalyst-forge/lib/tools => ../tools - -require ( - github.com/aws/aws-sdk-go v1.55.7 - github.com/aws/aws-sdk-go-v2/config v1.29.18 - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 - github.com/input-output-hk/catalyst-forge/lib/schema v0.0.0 - github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0 - github.com/stretchr/testify v1.10.0 -) - -require ( - dario.cat/mergo v1.0.1 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.0.0 // indirect - github.com/adrg/xdg v0.5.3 // indirect - github.com/aws/aws-sdk-go-v2 v1.36.6 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.71 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect - github.com/aws/smithy-go v1.22.4 // indirect - github.com/cloudflare/circl v1.3.7 // indirect - github.com/cyphar/filepath-securejoin v0.3.6 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emirpasic/gods v1.18.1 // indirect - github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.12.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect - github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/lib/secrets/go.sum b/lib/secrets/go.sum deleted file mode 100644 index d3b10aa7..00000000 --- a/lib/secrets/go.sum +++ /dev/null @@ -1,175 +0,0 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= -github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= -github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= -github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.36.6 h1:zJqGjVbRdTPojeCGWn5IR5pbJwSQSBh5RWFTQcEQGdU= -github.com/aws/aws-sdk-go-v2 v1.36.6/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= -github.com/aws/aws-sdk-go-v2/config v1.29.18 h1:x4T1GRPnqKV8HMJOMtNktbpQMl3bIsfx8KbqmveUO2I= -github.com/aws/aws-sdk-go-v2/config v1.29.18/go.mod h1:bvz8oXugIsH8K7HLhBv06vDqnFv3NsGDt2Znpk7zmOU= -github.com/aws/aws-sdk-go-v2/credentials v1.17.71 h1:r2w4mQWnrTMJjOyIsZtGp3R3XGY3nqHn8C26C2lQWgA= -github.com/aws/aws-sdk-go-v2/credentials v1.17.71/go.mod h1:E7VF3acIup4GB5ckzbKFrCK0vTvEQxOxgdq4U3vcMCY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 h1:D9ixiWSG4lyUBL2DDNK924Px9V/NBVpML90MHqyTADY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33/go.mod h1:caS/m4DI+cij2paz3rtProRBI4s/+TCiWoaWZuQ9010= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 h1:osMWfm/sC/L4tvEdQ65Gri5ZZDCUpuYJZbTTDrsn4I0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37/go.mod h1:ZV2/1fbjOPr4G4v38G3Ww5TBT4+hmsK45s/rxu1fGy0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 h1:v+X21AvTb2wZ+ycg1gx+orkB/9U6L7AOp93R7qYxsxM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37/go.mod h1:G0uM1kyssELxmJ2VZEfG0q2npObR3BAkF3c1VsfVnfs= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 h1:vvbXsA2TVO80/KT7ZqCbx934dt6PY+vQ8hZpUZ/cpYg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18/go.mod h1:m2JJHledjBGNMsLOF1g9gbAxprzq3KjC8e4lxtn+eWg= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8 h1:HD6R8K10gPbN9CNqRDOs42QombXlYeLOr4KkIxe2lQs= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.8/go.mod h1:x66GdH8qjYTr6Kb4ik38Ewl6moLsg8igbceNsmxVxeA= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 h1:rGtWqkQbPk7Bkwuv3NzpE/scwwL9sC1Ul3tn9x83DUI= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.6/go.mod h1:u4ku9OLv4TO4bCPdxf4fA1upaMaJmP9ZijGk3AAOC6Q= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 h1:OV/pxyXh+eMA0TExHEC4jyWdumLxNbzz1P0zJoezkJc= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4/go.mod h1:8Mm5VGYwtm+r305FfPSuc+aFkrypeylGYhFim6XEPoc= -github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 h1:aUrLQwJfZtwv3/ZNG2xRtEen+NqI3iesuacjP51Mv1s= -github.com/aws/aws-sdk-go-v2/service/sts v1.34.1/go.mod h1:3wFBZKoWnX3r+Sm7in79i54fBmNfwhdNdQuscCw7QIk= -github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= -github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= -github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= -github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= -github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib/tools/go.mod b/lib/tools/go.mod index fb14829b..f2c1d36a 100644 --- a/lib/tools/go.mod +++ b/lib/tools/go.mod @@ -46,6 +46,4 @@ require ( replace github.com/input-output-hk/catalyst-forge/lib/providers => ../providers -replace github.com/input-output-hk/catalyst-forge/lib/secrets => ../secrets - replace github.com/input-output-hk/catalyst-forge/lib/schema => ../schema From 961cdb40bbe749e6e94fc5223369fcdfb19af183 Mon Sep 17 00:00:00 2001 From: Joshua Gilman Date: Thu, 24 Jul 2025 19:54:40 -0700 Subject: [PATCH 29/29] wip: fixes foundry operator --- foundry/operator/Earthfile | 1 - foundry/operator/go.mod | 2 -- 2 files changed, 3 deletions(-) diff --git a/foundry/operator/Earthfile b/foundry/operator/Earthfile index c48ab4ac..cd65ab2f 100644 --- a/foundry/operator/Earthfile +++ b/foundry/operator/Earthfile @@ -34,7 +34,6 @@ deps: COPY ../../lib/providers+src/src /lib/providers COPY ../../lib/schema+src/src /lib/schema COPY ../../lib/tools+src/src /lib/tools - COPY ../../lib/secrets+src/src /lib/secrets # Install go deps RUN mkdir -p /go/cache && mkdir -p /go/modcache diff --git a/foundry/operator/go.mod b/foundry/operator/go.mod index 636e9d4a..2363a94c 100644 --- a/foundry/operator/go.mod +++ b/foundry/operator/go.mod @@ -277,8 +277,6 @@ replace github.com/input-output-hk/catalyst-forge/lib/providers => ../../lib/pro replace github.com/input-output-hk/catalyst-forge/lib/schema => ../../lib/schema -replace github.com/input-output-hk/catalyst-forge/lib/provider/secrets => ../../lib/secrets - replace github.com/input-output-hk/catalyst-forge/lib/tools => ../../lib/tools replace github.com/input-output-hk/catalyst-forge/foundry/api => ../api