Print public HTTPS URL of uploaded artefact
After a successful S3 upload, log the HTTPS URL so the workflow run output shows where the artefact was published. Uses the regional virtual-hosted form for AWS S3 and path-style for custom endpoints, matching how NewClient configures the client. The URL is what the object would be served at if the bucket allows public reads — the orchestrator does not assert anything about the bucket's access policy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d8f5309a73
commit
78f63e640f
|
|
@ -174,6 +174,7 @@ func run(ctx context.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Println("Uploaded to:", upload.HTTPSURL(cfg.S3Bucket, key, cfg.S3Region, cfg.S3EndpointURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Outputs (fixed order so partial-write failures are reproducible)
|
// 8. Outputs (fixed order so partial-write failures are reproducible)
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,19 @@ func Upload(ctx context.Context, c PutObjectAPI, o Opts) (string, error) {
|
||||||
return fmt.Sprintf("s3://%s/%s", o.Bucket, o.Key), nil
|
return fmt.Sprintf("s3://%s/%s", o.Bucket, o.Key), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTPSURL returns the HTTPS form of an upload location. For AWS S3 it uses
|
||||||
|
// the regional virtual-hosted form; for a custom endpoint it appends the
|
||||||
|
// bucket and key path-style, matching how NewClient configures the client.
|
||||||
|
//
|
||||||
|
// The bucket may still be private — this is purely the URL where the object
|
||||||
|
// would be served if it (or its bucket) were publicly readable.
|
||||||
|
func HTTPSURL(bucket, key, region, endpointURL string) string {
|
||||||
|
if endpointURL != "" {
|
||||||
|
return strings.TrimRight(endpointURL, "/") + "/" + bucket + "/" + key
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("https://%s.s3.%s.amazonaws.com/%s", bucket, region, key)
|
||||||
|
}
|
||||||
|
|
||||||
// WriteFileForTest is exposed for use from this package's tests.
|
// WriteFileForTest is exposed for use from this package's tests.
|
||||||
func WriteFileForTest(path string, b []byte) error {
|
func WriteFileForTest(path string, b []byte) error {
|
||||||
return os.WriteFile(path, b, 0o600)
|
return os.WriteFile(path, b, 0o600)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,49 @@ func TestRenderKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHTTPSURL(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
bucket, key string
|
||||||
|
region string
|
||||||
|
endpoint string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "aws regional virtual-hosted",
|
||||||
|
bucket: "my-bucket", key: "releases/1.2.3/App.app.zip",
|
||||||
|
region: "ap-southeast-2",
|
||||||
|
want: "https://my-bucket.s3.ap-southeast-2.amazonaws.com/releases/1.2.3/App.app.zip",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aws us-east-1 still uses regional form",
|
||||||
|
bucket: "my-bucket", key: "k",
|
||||||
|
region: "us-east-1",
|
||||||
|
want: "https://my-bucket.s3.us-east-1.amazonaws.com/k",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "custom endpoint path-style",
|
||||||
|
bucket: "releases", key: "myapp/1.0.0/App.app.zip",
|
||||||
|
region: "auto", endpoint: "https://my-minio.example.com",
|
||||||
|
want: "https://my-minio.example.com/releases/myapp/1.0.0/App.app.zip",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "custom endpoint with trailing slash is normalised",
|
||||||
|
bucket: "b", key: "k",
|
||||||
|
region: "auto", endpoint: "https://example.com/",
|
||||||
|
want: "https://example.com/b/k",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
got := upload.HTTPSURL(c.bucket, c.key, c.region, c.endpoint)
|
||||||
|
if got != c.want {
|
||||||
|
t.Fatalf("got %q\nwant %q", got, c.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type fakePut struct {
|
type fakePut struct {
|
||||||
calls []*s3.PutObjectInput
|
calls []*s3.PutObjectInput
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue