From 719b0dd502702d347ac358f285e11d9362c7bbac Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Wed, 12 Aug 2026 01:05:39 +1000 Subject: [PATCH] Add artifactapi_remote_github_alpine resource Adds the metadata-only Alpine/apk analog of the github_deb/github_rpm remotes: exposes a GitHub repo's release .apk assets as an apk repository (synthesized APKINDEX) without precaching, redirecting downloads to a backing releases_remote. - register newRemoteResource("github_alpine") in provider Resources() - add NewRemoteGitHubAlpine convenience ctor - extend provider/metadata/ctor table tests + bump resource count to 22 - document github_alpine remote type in README - add examples/resources/artifactapi_remote_github_alpine/main.tf --- README.md | 18 +++++++- .../artifactapi_remote_github_alpine/main.tf | 44 +++++++++++++++++++ internal/provider/provider.go | 1 + internal/provider/provider_test.go | 3 +- internal/provider/resource_remote.go | 5 ++- internal/provider/resource_remote_test.go | 2 + 6 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 examples/resources/artifactapi_remote_github_alpine/main.tf diff --git a/README.md b/README.md index bd08672..900395c 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Available resource types: - `artifactapi_remote_goproxy` - `artifactapi_remote_github_rpm` - `artifactapi_remote_github_deb` +- `artifactapi_remote_github_alpine` #### Common Attributes @@ -96,11 +97,11 @@ Available resource types: | `ban_tags_enabled` | `false` | Enable tag banning | | `ban_tags` | | List of tags to ban | -#### Terraform / github_rpm / github_deb-specific Attributes +#### Terraform / github_rpm / github_deb / github_alpine-specific Attributes | Attribute | Default | Description | |-------------------|---------|----------------------------------------------------------| -| `releases_remote` | `""` | Name of a backend remote that serves the download bytes. Terraform uses it for download URL rewriting; `github_rpm`/`github_deb` 302-redirect `.rpm`/`.deb` downloads to it. | +| `releases_remote` | `""` | Name of a backend remote that serves the download bytes. Terraform uses it for download URL rewriting; `github_rpm`/`github_deb`/`github_alpine` 302-redirect `.rpm`/`.deb`/`.apk` downloads to it. | #### github_rpm-specific notes @@ -125,6 +126,19 @@ generic `github.com` remote that streams the `.deb` bytes; `.deb` downloads higher API rate limits. See `examples/resources/artifactapi_remote_github_deb/main.tf`. +#### github_alpine-specific notes + +`artifactapi_remote_github_alpine` is the Alpine/apk analog of `github_rpm`: it +exposes a GitHub repo's release `.apk` assets as an `apk` repository, synthesizing +the apk index (`APKINDEX.tar.gz`) from release metadata without precaching +packages. Set `base_url` to the releases API root +(`https://api.github.com/repos/{owner}/{repo}`) and `releases_remote` to a +generic `github.com` remote that streams the `.apk` bytes; `.apk` downloads +302-redirect there. `patterns` filters which release assets become packages +(regex on asset filename). `password` may hold a token for private repos or +higher API rate limits. See +`examples/resources/artifactapi_remote_github_alpine/main.tf`. + #### Example ```hcl diff --git a/examples/resources/artifactapi_remote_github_alpine/main.tf b/examples/resources/artifactapi_remote_github_alpine/main.tf new file mode 100644 index 0000000..845564a --- /dev/null +++ b/examples/resources/artifactapi_remote_github_alpine/main.tf @@ -0,0 +1,44 @@ +terraform { + required_providers { + artifactapi = { + source = "git.unkin.net/unkin/artifactapi" + version = "0.0.1" + } + } +} + +provider "artifactapi" { + endpoint = "https://artifactapi.example.com" +} + +# Backend generic remote that serves the actual .apk bytes from github.com. +# Its patterns must allowlist the target repo's release-download assets. +resource "artifactapi_remote_generic" "github" { + name = "github" + base_url = "https://github.com" + + patterns = [ + "goodtune/ghp/releases/download/.*\\.apk$", + ] +} + +# Metadata-only remote: scans goodtune/ghp releases for .apk assets and serves a +# synthesized apk repo (APKINDEX). Packages are never precached; downloads +# 302-redirect to the "github" remote above. +resource "artifactapi_remote_github_alpine" "goodtune_ghp" { + name = "goodtune-ghp" + base_url = "https://api.github.com/repos/goodtune/ghp" + description = "goodtune/ghp GitHub releases as an apk repo" + releases_remote = artifactapi_remote_generic.github.name + + mutable_ttl = 3600 + + # Optional: restrict which release assets become packages. + patterns = [ + ".*_x86_64\\.apk$", + ".*_noarch\\.apk$", + ] + + # Optional: token for private repos / higher GitHub API rate limits. + # password = var.github_token +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 24ae493..85a6603 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -70,6 +70,7 @@ func (p *ArtifactAPIProvider) Resources(_ context.Context) []func() resource.Res newRemoteResource("goproxy"), newRemoteResource("github_rpm"), newRemoteResource("github_deb"), + newRemoteResource("github_alpine"), NewVirtualResource, NewLocalTerraformResource, NewLocalPyPIResource, diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 6eaccce..75791ef 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -67,7 +67,7 @@ func TestProvider_Resources(t *testing.T) { resources := p.Resources(context.Background()) // 13 remote resource types + 1 virtual + local_terraform/pypi/rpm/deb/alpine/docker/generic = 21 - expectedCount := 21 + expectedCount := 22 if len(resources) != expectedCount { t.Fatalf("expected %d resources, got %d", expectedCount, len(resources)) } @@ -109,6 +109,7 @@ func TestProvider_Resources_ContainsExpectedTypes(t *testing.T) { "artifactapi_remote_goproxy", "artifactapi_remote_github_rpm", "artifactapi_remote_github_deb", + "artifactapi_remote_github_alpine", "artifactapi_virtual", "artifactapi_local_terraform", "artifactapi_local_pypi", diff --git a/internal/provider/resource_remote.go b/internal/provider/resource_remote.go index 0a43da7..6ec6ea5 100644 --- a/internal/provider/resource_remote.go +++ b/internal/provider/resource_remote.go @@ -69,6 +69,9 @@ func NewRemoteTerraform() resource.Resource { return &remoteResource{packageType func NewRemoteGoProxy() resource.Resource { return &remoteResource{packageType: "goproxy"} } func NewRemoteGitHubRPM() resource.Resource { return &remoteResource{packageType: "github_rpm"} } func NewRemoteGitHubDeb() resource.Resource { return &remoteResource{packageType: "github_deb"} } +func NewRemoteGitHubAlpine() resource.Resource { + return &remoteResource{packageType: "github_alpine"} +} func (r *remoteResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_remote_" + r.packageType @@ -148,7 +151,7 @@ func (r *remoteResource) Schema(_ context.Context, _ resource.SchemaRequest, res ElementType: types.StringType, }, "releases_remote": schema.StringAttribute{ - Description: "Name of a backend remote that serves the actual download bytes. Used by the terraform remote (download URL rewriting) and the github_rpm/github_deb remotes (302 redirect of .rpm/.deb downloads to a generic github.com remote).", + Description: "Name of a backend remote that serves the actual download bytes. Used by the terraform remote (download URL rewriting) and the github_rpm/github_deb/github_alpine remotes (302 redirect of .rpm/.deb/.apk downloads to a generic github.com remote).", Optional: true, Computed: true, Default: stringdefault.StaticString(""), }, "upstream_dial_timeout": schema.Int64Attribute{ diff --git a/internal/provider/resource_remote_test.go b/internal/provider/resource_remote_test.go index 0515102..151e316 100644 --- a/internal/provider/resource_remote_test.go +++ b/internal/provider/resource_remote_test.go @@ -411,6 +411,7 @@ func TestRemoteResource_Metadata(t *testing.T) { {"npm", "artifactapi_remote_npm"}, {"github_rpm", "artifactapi_remote_github_rpm"}, {"github_deb", "artifactapi_remote_github_deb"}, + {"github_alpine", "artifactapi_remote_github_alpine"}, } for _, tt := range tests { @@ -523,6 +524,7 @@ func TestNewRemoteResource_Constructors(t *testing.T) { {"goproxy", func() resource.Resource { return NewRemoteGoProxy() }, "goproxy"}, {"github_rpm", func() resource.Resource { return NewRemoteGitHubRPM() }, "github_rpm"}, {"github_deb", func() resource.Resource { return NewRemoteGitHubDeb() }, "github_deb"}, + {"github_alpine", func() resource.Resource { return NewRemoteGitHubAlpine() }, "github_alpine"}, } for _, tt := range tests {