From db3860328b7b13c4eceddd7996668f40d0ad6961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Balv=C3=ADn?= Date: Sun, 26 Jul 2026 20:29:01 +0200 Subject: [PATCH] chore: migrate CI to Gitea actions and update module path --- {.forgejo => .gitea}/workflows/release.yml | 40 +++++++++++----------- {.forgejo => .gitea}/workflows/test.yml | 12 +++---- CHANGELOG.md | 4 +-- CONTRIBUTING.md | 22 ++++++------ README.md | 6 ++-- cmd/server/main.go | 6 ++-- docs/library-usage.md | 6 ++-- examples/minimal/main.go | 2 +- go.mod | 4 +-- go.sum | 4 +-- internal/config/config.go | 2 +- internal/email/sender.go | 4 +-- internal/handler/contact.go | 8 ++--- 13 files changed, 60 insertions(+), 60 deletions(-) rename {.forgejo => .gitea}/workflows/release.yml (77%) rename {.forgejo => .gitea}/workflows/test.yml (71%) diff --git a/.forgejo/workflows/release.yml b/.gitea/workflows/release.yml similarity index 77% rename from .forgejo/workflows/release.yml rename to .gitea/workflows/release.yml index 43c6870..3a24c05 100644 --- a/.forgejo/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: codeberg-small + runs-on: fedora strategy: fail-fast: false matrix: @@ -20,9 +20,9 @@ jobs: - goos: freebsd goarch: arm64 steps: - - uses: https://data.forgejo.org/actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: https://data.forgejo.org/actions/setup-go@v5 + - uses: actions/setup-go@v5 with: go-version: "1.26" @@ -32,7 +32,7 @@ jobs: - name: Build id: build env: - REF: ${{ forgejo.ref }} + REF: ${{ gitea.ref }} run: | set -euo pipefail @@ -45,9 +45,9 @@ jobs: fi VERSION_NO_V="${VERSION#v}" - echo "version_no_v=${VERSION_NO_V}" >> "$FORGEJO_OUTPUT" + echo "version_no_v=${VERSION_NO_V}" >> "$GITEA_OUTPUT" - LDFLAGS="-s -w -X codeberg.org/petrbalvin/nuntius/internal/version.Version=${VERSION}" + LDFLAGS="-s -w -X sourcedock.dev/petrbalvin/nuntius/internal/version.Version=${VERSION}" mkdir -p bin GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \ go build -ldflags "$LDFLAGS" \ @@ -55,26 +55,26 @@ jobs: ./cmd/server - name: Upload artifact - uses: https://data.forgejo.org/actions/upload-artifact@v3 + uses: actions/upload-artifact@v3 with: name: nuntius-${{ matrix.goos }}-${{ matrix.goarch }} path: bin/nuntius-${{ steps.build.outputs.version_no_v }}-${{ matrix.goos }}-${{ matrix.goarch }} if-no-files-found: error release: - runs-on: codeberg-tiny + runs-on: fedora needs: build steps: - - uses: https://data.forgejo.org/actions/checkout@v4 + - uses: actions/checkout@v4 - name: Download all artifacts - uses: https://data.forgejo.org/actions/download-artifact@v3 + uses: actions/download-artifact@v3 with: path: dist - name: Extract CHANGELOG section env: - VERSION: ${{ forgejo.ref_name }} + VERSION: ${{ gitea.ref_name }} run: | set -euo pipefail VERSION_NO_V="${VERSION#v}" @@ -96,7 +96,7 @@ jobs: - name: Create release env: - FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -euo pipefail # JSON-escape the release body with sed: backslashes first, then @@ -111,13 +111,13 @@ jobs: BODY="\"${BODY}\"" response=$(curl -sS -w '\n%{http_code}' \ - -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -X POST \ - "${FORGEJO_SERVER_URL}/api/v1/repos/${FORGEJO_REPOSITORY}/releases" \ + "${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases" \ -d "{ - \"tag_name\": \"${FORGEJO_REF_NAME}\", - \"name\": \"${FORGEJO_REF_NAME}\", + \"tag_name\": \"${GITEA_REF_NAME}\", + \"name\": \"${GITEA_REF_NAME}\", \"body\": ${BODY}, \"draft\": false, \"prerelease\": false @@ -139,7 +139,7 @@ jobs: - name: Upload assets env: - FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -euo pipefail RELEASE_ID=$(cat release-id.txt) @@ -150,11 +150,11 @@ jobs: fname=$(basename "$binary") echo "Uploading ${fname}..." http_code=$(curl -sS -o /dev/null -w '%{http_code}' \ - -H "Authorization: token ${FORGEJO_TOKEN}" \ + -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/octet-stream" \ -X POST \ --data-binary "@${binary}" \ - "${FORGEJO_SERVER_URL}/api/v1/repos/${FORGEJO_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${fname}") + "${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${fname}") echo " HTTP ${http_code}" if [ "$http_code" != "201" ]; then echo "Failed to upload ${fname}" @@ -163,5 +163,5 @@ jobs: done echo - echo "Release ${FORGEJO_REF_NAME} is live with the following assets:" + echo "Release ${GITEA_REF_NAME} is live with the following assets:" ls -lh dist/nuntius-*/ diff --git a/.forgejo/workflows/test.yml b/.gitea/workflows/test.yml similarity index 71% rename from .forgejo/workflows/test.yml rename to .gitea/workflows/test.yml index 0e7a31f..3f6181c 100644 --- a/.forgejo/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -8,11 +8,11 @@ on: jobs: vet: - runs-on: codeberg-small + runs-on: fedora steps: - - uses: https://data.forgejo.org/actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: https://data.forgejo.org/actions/setup-go@v5 + - uses: actions/setup-go@v5 with: go-version: "1.26" @@ -28,12 +28,12 @@ jobs: run: go vet ./... test: - runs-on: codeberg-small + runs-on: fedora needs: vet steps: - - uses: https://data.forgejo.org/actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: https://data.forgejo.org/actions/setup-go@v5 + - uses: actions/setup-go@v5 with: go-version: "1.26" diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f9f486..1898145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ First stable release of nuntius: a small, opinionated, modular contact form backend written in Go. A single static binary, four form kinds out of the box, SMTP delivery, a JSONL newsletter log, strict TOML configuration, and env-var secrets. Its only dependency outside the standard library is the first-party -[interpres](https://codeberg.org/petrbalvin/interpres) TOML parser. +[interpres](https://sourcedock.dev/petrbalvin/interpres) ### Added @@ -49,4 +49,4 @@ secrets. Its only dependency outside the standard library is the first-party - **docs/** — `architecture.md`, `configuration.md`, `api-reference.md`, `deployment.md`, `security.md`, `library-usage.md`. -[1.0.0]: https://codeberg.org/petrbalvin/nuntius/releases/tag/v1.0.0 +[1.0.0]: https://sourcedock.dev/petrbalvin/nuntius/releases/tag/v1.0.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34ec387..f733903 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ See [Cutting a release](#cutting-a-release) for the full procedure. ### Quick Start ```bash -git clone https://codeberg.org/petrbalvin/nuntius.git +git clone https://sourcedock.dev/petrbalvin/nuntius.git cd nuntius just install # go mod tidy + go mod download (no third-party modules — no-op for this project) just build # → ./bin/nuntius (with -ldflags="-s -w") @@ -203,11 +203,11 @@ graph TD ## CI -This project uses **Forgejo Actions** for continuous integration. The two workflow files live under `.forgejo/workflows/` and are the source of truth for what runs on every push and on every tagged release. +This project uses **Gitea Actions** for continuous integration. The two workflow files live under `.gitea/workflows/` and are the source of truth for what runs on every push and on every tagged release. -### Test workflow — `.forgejo/workflows/test.yml` +### Test workflow — `.gitea/workflows/test.yml` -Triggered on every push to `development` and on every pull request targeting `development`. `main` is excluded on purpose — it only ever receives release tags, and the release workflow builds the binaries itself. Three jobs run in sequence, all on the `codeberg-small` runner: +Triggered on every push to `development` and on every pull request targeting `development`. `main` is excluded on purpose — it only ever receives release tags, and the release workflow builds the binaries itself. Three jobs run in sequence, all on the `fedora` runner: | Job | What it does | Why it exists | |---|---|---| @@ -225,23 +225,23 @@ just build ./bin/nuntius --version # sanity-check the new flag ``` -### Release workflow — `.forgejo/workflows/release.yml` +### Release workflow — `.gitea/workflows/release.yml` Triggered by pushing a tag that matches `v*.*.*` (e.g. `v1.0.0`, `v1.2.3`) onto `main`. The merge from `development` into `main` is the maintainer's responsibility and happens before the tag is pushed — this workflow does not merge anything. Two jobs: -1. **`build`** — Runs on a `codeberg-small` runner in a 4-way matrix: `linux/amd64`, `linux/arm64`, `freebsd/amd64`, `freebsd/arm64`. The default `actions/checkout@v4` checks out the tagged commit (the trigger was a tag push), which is exactly the commit on `main` we want to ship. The version is baked in via `-ldflags`: +1. **`build`** — Runs on a `fedora` runner in a 4-way matrix: `linux/amd64`, `linux/arm64`, `freebsd/amd64`, `freebsd/arm64`. The default `actions/checkout@v4` checks out the tagged commit (the trigger was a tag push), which is exactly the commit on `main` we want to ship. The version is baked in via `-ldflags`: ```bash - -X codeberg.org/petrbalvin/nuntius/internal/version.Version=${VERSION#v} + -X sourcedock.dev/petrbalvin/nuntius/internal/version.Version=${VERSION#v} ``` The resulting binary is uploaded as a workflow artifact and smoke-tested with `--version` on the build host. -2. **`release`** — Runs on a `codeberg-tiny` runner (no Go toolchain needed). Downloads all artifacts, extracts the matching section from `CHANGELOG.md` for the tagged version, creates a release via the Forgejo REST API, and uploads each binary as a release asset. The release is **non-draft, non-prerelease**; if the CHANGELOG section is missing, the job fails fast so a release cannot ship without notes. +2. **`release`** — Runs on a `fedora` runner (no Go toolchain needed). Downloads all artifacts, extracts the matching section from `CHANGELOG.md` for the tagged version, creates a release via the Gitea REST API, and uploads each binary as a release asset. The release is **non-draft, non-prerelease**; if the CHANGELOG section is missing, the job fails fast so a release cannot ship without notes. ### Cutting a release 1. Bump `Version` in `internal/version/version.go`. 2. Add a new `## [X.Y.Z] — YYYY-MM-DD` section at the top of `CHANGELOG.md`. 3. Make sure CI is green on `development` (pushes and PRs against `development` are what the test workflow runs on). -4. Merge `development` into `main` (e.g. open a PR on Forgejo, or `git checkout main && git merge --no-ff development && git push origin main`). This is the **only** step where `main` is updated outside of a tag push. +4. Merge `development` into `main` (e.g. open a PR on Gitea, or `git checkout main && git merge --no-ff development && git push origin main`). This is the **only** step where `main` is updated outside of a tag push. 5. Tag the `main` tip and push the tag: ```bash git tag -a vX.Y.Z -m "nuntius vX.Y.Z" @@ -250,7 +250,7 @@ Triggered by pushing a tag that matches `v*.*.*` (e.g. `v1.0.0`, `v1.2.3`) onto ``` 6. The release workflow builds the four platform binaries and creates the release with the CHANGELOG section as the body. No CI step performs the merge — that already happened in step 4. -If the release job fails, the tag can be deleted and re-pushed; the workflow re-runs on the new tag push. Do not re-tag an already-released commit — the Forgejo API rejects duplicate release tag names. +If the release job fails, the tag can be deleted and re-pushed; the workflow re-runs on the new tag push. Do not re-tag an already-released commit — the Gitea API rejects duplicate release tag names. ## Adding a New Form Type @@ -264,7 +264,7 @@ The four current types (`contact`, `feedback`, `newsletter`, `generic`) live in ## Report a Bug -Open an issue at with: +Open an issue at with: - nuntius version (`./bin/nuntius --version`). - Operating system and architecture. diff --git a/README.md b/README.md index ef3ae94..f2df97b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ ```bash # 1. Clone -git clone https://codeberg.org/petrbalvin/nuntius.git +git clone https://sourcedock.dev/petrbalvin/nuntius.git cd nuntius # 2. Build @@ -121,7 +121,7 @@ await fetch(`${import.meta.env.VITE_NUNTIUS_URL || ''}/api/nuntius/contact`, { `pkg/contactform` is a small, dependency-free Go package that you can import into any project: ```go -import "codeberg.org/petrbalvin/nuntius/pkg/contactform" +import "sourcedock.dev/petrbalvin/nuntius/pkg/contactform" req := &contactform.Request{ Name: "Jane", @@ -170,7 +170,7 @@ Form types and full schema: [`docs/configuration.md`](docs/configuration.md). Se - **Go 1.26+** (uses Go 1.22+ `http.ServeMux` method patterns and `log/slog`) - An **SMTP** account (Yandex, Mailgun, Postmark, your own Postfix, …) -- **No other runtime dependencies.** No Node, no Python, no Redis, no Postgres. Configuration is TOML parsed via the first-party [`interpres`](https://codeberg.org/petrbalvin/interpres) library; newsletter storage is an append-only JSONL file via `bufio`. +- **No other runtime dependencies.** No Node, no Python, no Redis, no Postgres. Configuration is TOML parsed via the first-party [`interpres`](https://sourcedock.dev/petrbalvin/interpres) library; newsletter storage is an append-only JSONL file via `bufio`. ## Development diff --git a/cmd/server/main.go b/cmd/server/main.go index e16be72..e6158d3 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -19,9 +19,9 @@ import ( "syscall" "time" - "codeberg.org/petrbalvin/nuntius/internal/config" - "codeberg.org/petrbalvin/nuntius/internal/handler" - "codeberg.org/petrbalvin/nuntius/internal/version" + "sourcedock.dev/petrbalvin/nuntius/internal/config" + "sourcedock.dev/petrbalvin/nuntius/internal/handler" + "sourcedock.dev/petrbalvin/nuntius/internal/version" ) func main() { diff --git a/docs/library-usage.md b/docs/library-usage.md index ffd3a7e..ca7a4fb 100644 --- a/docs/library-usage.md +++ b/docs/library-usage.md @@ -5,7 +5,7 @@ ## Installation ```bash -go get codeberg.org/petrbalvin/nuntius/pkg/contactform +go get sourcedock.dev/petrbalvin/nuntius/pkg/contactform ``` Because nuntius ships with no `go.sum` entries from third-party modules, this import pulls in only stdlib transitively. @@ -118,7 +118,7 @@ import ( "fmt" "os" - "codeberg.org/petrbalvin/nuntius/pkg/contactform" + "sourcedock.dev/petrbalvin/nuntius/pkg/contactform" ) func main() { @@ -175,7 +175,7 @@ import ( "log" "net/http" - "codeberg.org/petrbalvin/nuntius/pkg/contactform" + "sourcedock.dev/petrbalvin/nuntius/pkg/contactform" ) func contactHandler(w http.ResponseWriter, r *http.Request) { diff --git a/examples/minimal/main.go b/examples/minimal/main.go index 3d8f110..7b1dd7b 100644 --- a/examples/minimal/main.go +++ b/examples/minimal/main.go @@ -8,7 +8,7 @@ import ( "fmt" "os" - "codeberg.org/petrbalvin/nuntius/pkg/contactform" + "sourcedock.dev/petrbalvin/nuntius/pkg/contactform" ) func main() { diff --git a/go.mod b/go.mod index ff8c6ad..bbd1d2c 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ -module codeberg.org/petrbalvin/nuntius +module sourcedock.dev/petrbalvin/nuntius go 1.26 -require codeberg.org/petrbalvin/interpres v1.0.0 +require sourcedock.dev/petrbalvin/interpres v1.1.1 diff --git a/go.sum b/go.sum index 868f1b4..d163d79 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -codeberg.org/petrbalvin/interpres v1.0.0 h1:bnY6zSekKklss+w/95O/0GCO1col05pV4HE8JsVXQN4= -codeberg.org/petrbalvin/interpres v1.0.0/go.mod h1:sWgi5ijKNNLu5sCtjix9jG/guhdnDRlROENrFhrIt90= +sourcedock.dev/petrbalvin/interpres v1.1.1 h1:W0HYj8kHikuy1BZePPL4RaSEuv3TNX7YpdP1vvpkP54= +sourcedock.dev/petrbalvin/interpres v1.1.1/go.mod h1:kyJWrbwVykxCiW250V6zZO2QUKNlAeFn+pwqzr+Hn2U= diff --git a/internal/config/config.go b/internal/config/config.go index 86f1ebc..22be5e0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -16,7 +16,7 @@ import ( "strconv" "strings" - "codeberg.org/petrbalvin/interpres" + "sourcedock.dev/petrbalvin/interpres" ) // ValidFormTypes lists the form types nuntius knows how to handle. diff --git a/internal/email/sender.go b/internal/email/sender.go index 085d080..675a23d 100644 --- a/internal/email/sender.go +++ b/internal/email/sender.go @@ -10,8 +10,8 @@ import ( "net/smtp" "time" - "codeberg.org/petrbalvin/nuntius/internal/config" - "codeberg.org/petrbalvin/nuntius/pkg/contactform" + "sourcedock.dev/petrbalvin/nuntius/internal/config" + "sourcedock.dev/petrbalvin/nuntius/pkg/contactform" ) // FormSender delivers contact form submissions for a single form diff --git a/internal/handler/contact.go b/internal/handler/contact.go index d9fd0b9..7f611df 100644 --- a/internal/handler/contact.go +++ b/internal/handler/contact.go @@ -11,10 +11,10 @@ import ( "sync" "time" - "codeberg.org/petrbalvin/nuntius/internal/config" - "codeberg.org/petrbalvin/nuntius/internal/email" - "codeberg.org/petrbalvin/nuntius/internal/storage" - "codeberg.org/petrbalvin/nuntius/pkg/contactform" + "sourcedock.dev/petrbalvin/nuntius/internal/config" + "sourcedock.dev/petrbalvin/nuntius/internal/email" + "sourcedock.dev/petrbalvin/nuntius/internal/storage" + "sourcedock.dev/petrbalvin/nuntius/pkg/contactform" ) // ContactHandler serves one or more contact forms, dispatched by URL path.