Publish from Gitea: releases, CI and install docs

Gitea implements no Terraform provider registry, so distribution goes
through release archives plus a filesystem mirror. GoReleaser targets
the Gitea release API; the archive names follow HashiCorp's convention
because that is the only shape a filesystem mirror recognises.

No GPG signing: signatures are a registry-protocol requirement and a
filesystem mirror never checks them.

Cross-repo links point at Gitea; Go module paths deliberately do not.
This commit is contained in:
2026-08-09 12:37:07 +03:00
parent a6d8aa8b52
commit abe4444d2b
4 changed files with 198 additions and 10 deletions

View File

@@ -0,0 +1,40 @@
name: build
on:
push:
branches: [main]
pull_request:
workflow_dispatch: {}
env:
GO_VERSION: "1.25.x"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache-dependency-path: go.sum
- name: Format
run: test -z "$(gofmt -l .)" || { gofmt -l .; echo "run gofmt -w ."; exit 1; }
- name: Vet
run: go vet ./...
- name: Build
run: go build ./...
- name: Test
run: go test ./... -count=1
# The bridge in pulumi-dokploy reaches the provider through `shim`, and
# `internal/provider` is not importable from outside this module. If that
# entry point ever stops compiling on its own, the Pulumi build breaks
# somewhere far away from the cause.
- name: The shim package still builds standalone
run: go build ./shim/

View File

@@ -0,0 +1,27 @@
name: release
on:
push:
tags: ["v*.*.*"]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# GoReleaser builds the changelog from history, so a shallow clone
# would produce an empty one.
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: "1.25.x"
- uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean
env:
# Injected by Gitea for every workflow run; no personal token needed.
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

89
.goreleaser.yml Normal file
View File

@@ -0,0 +1,89 @@
# Publishes provider binaries to a Gitea release.
#
# Gitea has no Terraform provider registry -- that protocol is not one of the
# ~20 package types it implements -- so these archives are consumed through a
# filesystem mirror instead. See "Installing" in the README.
#
# The archive names follow HashiCorp's convention
# (terraform-provider-NAME_VERSION_OS_ARCH.zip) because a filesystem mirror
# recognises exactly that shape, and nothing else.
version: 2
project_name: terraform-provider-dokploy
before:
hooks:
- go mod download
builds:
- id: provider
main: .
binary: "{{ .ProjectName }}_v{{ .Version }}"
env:
- CGO_ENABLED=0
flags:
- -trimpath
ldflags:
- -s -w
- -X main.version={{ .Version }}
goos:
- darwin
- linux
- windows
- freebsd
goarch:
- amd64
- arm64
- "386"
ignore:
- goos: darwin
goarch: "386"
archives:
- id: provider
formats: [zip]
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
files:
- none*
checksum:
name_template: "{{ .ProjectName }}_{{ .Version }}_SHA256SUMS"
algorithm: sha256
# No `signs:` block on purpose. GPG signatures are required by the Terraform
# *registry* protocol; a filesystem mirror never checks them. Adding signing
# here would imply a verification step that nothing performs.
changelog:
use: git
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
- "^chore:"
gitea_urls:
api: https://gitea.coolify.vojtkov.dev/api/v1
download: https://gitea.coolify.vojtkov.dev
release:
gitea:
owner: usr_unknown
name: terraform-provider-dokploy
header: |
## terraform-provider-dokploy {{ .Tag }}
Gitea cannot serve the Terraform registry protocol, so install through a
filesystem mirror:
```bash
VERSION={{ trimprefix .Tag "v" }}
OS_ARCH="$(go env GOOS)_$(go env GOARCH)"
DEST=~/.local/share/terraform/plugins/registry.terraform.io/maxvojtkov/dokploy/$VERSION/$OS_ARCH
mkdir -p "$DEST"
unzip -j terraform-provider-dokploy_${VERSION}_${OS_ARCH}.zip -d "$DEST"
```
Then point Terraform at the mirror -- the exact `~/.terraformrc` block is
printed by `make install`.

View File

@@ -56,8 +56,32 @@ resource "dokploy_domain" "api" {
## Installing ## Installing
The provider is not published to a registry yet. Build it and install it into a This provider is distributed through
local filesystem mirror: [Gitea releases](https://gitea.coolify.vojtkov.dev/usr_unknown/terraform-provider-dokploy/releases),
not a Terraform registry — Gitea implements about twenty package registries,
and the Terraform provider protocol is not one of them. So installation goes
through a **filesystem mirror**, which is Terraform's supported way to use a
provider that no registry serves.
### From a release
```bash
VERSION=0.1.0
OS_ARCH="$(go env GOOS)_$(go env GOARCH)"
BASE=https://gitea.coolify.vojtkov.dev/usr_unknown/terraform-provider-dokploy/releases/download
DEST=~/.local/share/terraform/plugins/registry.terraform.io/maxvojtkov/dokploy/$VERSION/$OS_ARCH
mkdir -p "$DEST"
curl -fsSLO "$BASE/v$VERSION/terraform-provider-dokploy_${VERSION}_${OS_ARCH}.zip"
unzip -j "terraform-provider-dokploy_${VERSION}_${OS_ARCH}.zip" -d "$DEST"
```
Each release also carries a `_SHA256SUMS` file, worth checking before you
unzip. There are no GPG signatures: those are required by the registry
protocol, and a filesystem mirror never verifies them, so publishing one would
imply a check that nothing performs.
### From source
```bash ```bash
make install make install
@@ -202,7 +226,7 @@ auth and redirects — behind one call:
```hcl ```hcl
module "storefront" { module "storefront" {
source = "github.com/maxvojtkov/terraform-provider-dokploy//modules/web-service" source = "git::https://gitea.coolify.vojtkov.dev/usr_unknown/terraform-provider-dokploy.git//modules/web-service"
name = "storefront" name = "storefront"
environment_id = dokploy_project.shop.default_environment_id environment_id = dokploy_project.shop.default_environment_id
@@ -253,13 +277,13 @@ curl -X POST "$DOKPLOY_HOST/api/application.deploy" \
### From CI ### From CI
[`dokploy-deploy-action`](https://github.com/maxvojtkov/dokploy-deploy-action) [`dokploy-deploy-action`](https://gitea.coolify.vojtkov.dev/usr_unknown/dokploy-deploy-action)
is the same call with the parts that matter in a pipeline: it waits for the is the same call with the parts that matter in a pipeline: it waits for the
build, fails the job when the deployment fails, and prints the build log. build, fails the job when the deployment fails, and prints the build log.
It runs on GitHub Actions and Gitea Actions. It runs on GitHub Actions and Gitea Actions.
```yaml ```yaml
- uses: maxvojtkov/dokploy-deploy-action@v1 - uses: https://gitea.coolify.vojtkov.dev/usr_unknown/dokploy-deploy-action@v1
with: with:
host: ${{ secrets.DOKPLOY_HOST }} host: ${{ secrets.DOKPLOY_HOST }}
api-key: ${{ secrets.DOKPLOY_API_KEY }} api-key: ${{ secrets.DOKPLOY_API_KEY }}
@@ -325,11 +349,13 @@ Because this is a standard Terraform provider, Pulumi consumes it through
[`pulumi-terraform-bridge`](https://github.com/pulumi/pulumi-terraform-bridge) [`pulumi-terraform-bridge`](https://github.com/pulumi/pulumi-terraform-bridge)
— no reimplementation needed. Two routes: — no reimplementation needed. Two routes:
**Dynamic bridge (no build step).** Point Pulumi at the provider binary and use **Dynamic bridge (no build step).** Point Pulumi at a provider binary and use
it straight away: it straight away. The usual `owner/name` shorthand resolves through the
Terraform registry, which does not serve this provider, so give a path
instead — `make build` produces one:
```bash ```bash
pulumi package add terraform-provider maxvojtkov/dokploy pulumi package add terraform-provider ./terraform-provider-dokploy
``` ```
Pulumi generates an SDK for your language on the spot. This is the fastest path Pulumi generates an SDK for your language on the spot. This is the fastest path
@@ -337,8 +363,9 @@ and keeps you in lockstep with the Terraform provider.
**Static bridge (a published SDK).** For a first-class, versioned package with **Static bridge (a published SDK).** For a first-class, versioned package with
richer types, use richer types, use
[`pulumi-dokploy`](https://github.com/maxvojtkov/pulumi-dokploy), which wraps [`pulumi-dokploy`](https://gitea.coolify.vojtkov.dev/usr_unknown/pulumi-dokploy), which wraps
this provider and ships SDKs for TypeScript, Python, Go and .NET: this provider and ships SDKs for TypeScript, Python, Go and .NET from this
Gitea instance's package registries:
```bash ```bash
npm install @maxvojtkov/pulumi-dokploy npm install @maxvojtkov/pulumi-dokploy
@@ -347,6 +374,11 @@ go get github.com/maxvojtkov/pulumi-dokploy/sdk/go/dokploy
dotnet add package Maxvojtkov.Dokploy dotnet add package Maxvojtkov.Dokploy
``` ```
Each of those needs its registry pointed at Gitea first — the one-time
configuration per language is in that repository's
[Installing](https://gitea.coolify.vojtkov.dev/usr_unknown/pulumi-dokploy#installing)
section.
That repository holds nothing but the mapping — every resource, schema and API That repository holds nothing but the mapping — every resource, schema and API
call still comes from here, so the two providers move together. call still comes from here, so the two providers move together.