<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>The Wombelix Post - sourcehut</title><link href="https://dominik.wombacher.cc/" rel="alternate"/><link href="/feeds/tag_sourcehut.atom.xml" rel="self"/><id>https://dominik.wombacher.cc/</id><updated>2025-07-28T00:00:00+02:00</updated><entry><title>New release of sr.ht go lib and terraform provider to fix update repo bug</title><link href="https://dominik.wombacher.cc/posts/new-release-of-srht-go-lib-and-terraform-provider-to-fix-update-repo-bug.html" rel="alternate"/><published>2025-07-28T00:00:00+02:00</published><updated>2025-07-28T00:00:00+02:00</updated><author><name>Dominik Wombacher</name></author><id>tag:dominik.wombacher.cc,2025-07-28:/posts/new-release-of-srht-go-lib-and-terraform-provider-to-fix-update-repo-bug.html</id><summary type="html">&lt;!-- SPDX-FileCopyrightText: 2025 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;Today I released new versions of &lt;a class="reference external" href="https://git.sr.ht/~wombelix/terraform-provider-sourcehut"&gt;terraform-provider-sourcehut&lt;/a&gt; (v0.2.1)
and the related Go library &lt;a class="reference external" href="https://git.sr.ht/~wombelix/sourcehut-go"&gt;sourcehut-go&lt;/a&gt; (v0.1.1).
This is a bugfix release to address an issue when updating  ... &lt;a class="read-more" href="/posts/new-release-of-srht-go-lib-and-terraform-provider-to-fix-update-repo-bug.html"&gt; [read more]&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;!-- SPDX-FileCopyrightText: 2025 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;Today I released new versions of &lt;a class="reference external" href="https://git.sr.ht/~wombelix/terraform-provider-sourcehut"&gt;terraform-provider-sourcehut&lt;/a&gt; (v0.2.1)
and the related Go library &lt;a class="reference external" href="https://git.sr.ht/~wombelix/sourcehut-go"&gt;sourcehut-go&lt;/a&gt; (v0.1.1).
This is a bugfix release to address an issue when updating a repository description.&lt;/p&gt;
&lt;p&gt;End of last year, I published the &lt;a class="reference external" href="https://dominik.wombacher.cc/posts/release-sourcehut-srht-opentofu-terraform-provider-and-go-library.html"&gt;initial version of the provider and library&lt;/a&gt;
and started using it for my &lt;a class="reference external" href="https://dominik.wombacher.cc/posts/opentofu-based-management-of-my-git-repositories.html"&gt;OpenTofu based management of my git repositories&lt;/a&gt;.
When I tried to update the description of an existing repository, the provider failed with a very generic error:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Multiple API errors occured&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This wasn't very helpful, so I started to dig into the code to find the root cause.&lt;/p&gt;
&lt;p&gt;The issue was in the &lt;cite&gt;sourcehut-go&lt;/cite&gt; library itself. The error handling for multiple errors was just
returning a static string instead of the actual error details from the API.
I improved the error handling to be more specific:&lt;/p&gt;
&lt;pre class="code diff literal-block"&gt;
&lt;span class="pygments-gd"&gt;--- a/errors.go&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+++ b/errors.go&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -4,6 +4,8 &amp;#64;&amp;#64;&lt;/span&gt;&lt;span class="pygments-w"&gt;

 &lt;/span&gt;package sourcehut&lt;span class="pygments-w"&gt;

&lt;/span&gt;&lt;span class="pygments-gi"&gt;+import &amp;quot;strings&amp;quot;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;// Ensure that the build fails if Error and Errors don't implement error.&lt;span class="pygments-w"&gt;
 &lt;/span&gt;var _, _ error = (*Error)(nil), (*Errors)(nil)&lt;span class="pygments-w"&gt;

&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -34,7 +36,18 &amp;#64;&amp;#64; type Errors []Error&lt;/span&gt;&lt;span class="pygments-w"&gt;

 &lt;/span&gt;// Error satisfies the error interface for Errors.&lt;span class="pygments-w"&gt;
 &lt;/span&gt;func (err Errors) Error() string {&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-       return &amp;quot;Multiple API errors occured&amp;quot;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       if len(err) == 0 {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               return &amp;quot;[WARN] Errors.Error() triggered with err length 0&amp;quot;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       }&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       if len(err) == 1 {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               return err[0].Error()&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       }&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       var details []string&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       for _, e := range err {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               details = append(details, e.Reason)&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       }&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       return strings.Join(details, &amp;quot;; &amp;quot;)&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;}&lt;span class="pygments-w"&gt;

 &lt;/span&gt;// StatusCode returns the HTTP status code of the request that unmarshaled this&lt;span class="pygments-w"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;With this change in place, the error message became much more useful:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;A repository with this name already exists.; validation failed&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This new error pointed me in the right direction. I checked the
&lt;a class="reference external" href="https://web.archive.org/web/20250207112955/https://man.sr.ht/git.sr.ht/api.md#repository-resource"&gt;git.sr.ht legacy API documentation&lt;/a&gt;
and found the problem. The API endpoint for updating a repository treats the &lt;cite&gt;name&lt;/cite&gt; field as optional.
If you provide a name that is different from the current one, it triggers a rename and a redirect.
If you provide the same name, it fails because a repository with that name already exists.&lt;/p&gt;
&lt;p&gt;To fix this, I changed the &lt;cite&gt;UpdateRepo&lt;/cite&gt; function to only include the &lt;cite&gt;name&lt;/cite&gt;
in the payload if it's actually different from the old name.&lt;/p&gt;
&lt;pre class="code diff literal-block"&gt;
&lt;span class="pygments-gd"&gt;--- a/git/git.go&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+++ b/git/git.go&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -8,6 +8,7 &amp;#64;&amp;#64; package git&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;import (&lt;span class="pygments-w"&gt;
 &lt;/span&gt;       &amp;quot;bytes&amp;quot;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;       &amp;quot;encoding/json&amp;quot;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       &amp;quot;fmt&amp;quot;&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;       &amp;quot;io&amp;quot;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;       &amp;quot;net/http&amp;quot;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;       &amp;quot;net/url&amp;quot;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gu"&gt;&amp;#64;&amp;#64; -152,15 +153,25 &amp;#64;&amp;#64; func (c *Client) NewRepo(name, description string, visibility RepoVisibility) (*&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;// If repo.Name differs from oldName, a redirect from the old name to the new&lt;span class="pygments-w"&gt;
 &lt;/span&gt;// name.&lt;span class="pygments-w"&gt;
 &lt;/span&gt;func (c *Client) UpdateRepo(oldName string, repo *Repo) error {&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-       jsonRepo, err := json.Marshal(struct {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-               Name string `json:&amp;quot;name&amp;quot;`&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-               Desc string `json:&amp;quot;description&amp;quot;`&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-               Visi string `json:&amp;quot;visibility&amp;quot;`&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-       }{&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-               Name: repo.Name,&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-               Desc: repo.Description,&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-               Visi: string(repo.Visibility),&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gd"&gt;-       })&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       updateData := make(map[string]interface{})&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       // Only include name if it's different from oldName (for renaming)&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       if repo.Name != &amp;quot;&amp;quot; &amp;amp;&amp;amp; repo.Name != oldName {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               updateData[&amp;quot;name&amp;quot;] = repo.Name&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       }&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       // Always include description, allows empty as well&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       updateData[&amp;quot;description&amp;quot;] = repo.Description&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       if repo.Visibility != &amp;quot;&amp;quot; {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               // Validate visibility value&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               if repo.Visibility != VisibilityPublic &amp;amp;&amp;amp; repo.Visibility != VisibilityUnlisted &amp;amp;&amp;amp; repo.Visibility != VisibilityPrivate {&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+                       return fmt.Errorf(&amp;quot;invalid visibility: %s (must be public, unlisted, or private)&amp;quot;, repo.Visibility)&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               }&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+               updateData[&amp;quot;visibility&amp;quot;] = string(repo.Visibility)&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       }&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-gi"&gt;+       jsonRepo, err := json.Marshal(updateData)&lt;/span&gt;&lt;span class="pygments-w"&gt;
 &lt;/span&gt;       if err != nil {&lt;span class="pygments-w"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;I used the opportunity to refactor the code a bit and to add a value validation for the repo visibility.&lt;/p&gt;
&lt;p&gt;With these two fixes, updating a repository description with my sourcehut terraform provider now works as expected.&lt;/p&gt;
&lt;p&gt;The new versions are available in the &lt;a class="reference external" href="https://search.opentofu.org/provider/wombelix/sourcehut/latest"&gt;OpenTofu&lt;/a&gt;
and &lt;a class="reference external" href="https://registry.terraform.io/providers/wombelix/sourcehut/latest"&gt;Terraform&lt;/a&gt; registry.&lt;/p&gt;
&lt;p&gt;The OpenTofu Registry WebUI is often behind the API, even if it doesn't show v0.2.1 yet, it is already available.
You can verify it by running &lt;code&gt;curl https://registry.opentofu.org/v1/providers/wombelix/sourcehut/versions&lt;/code&gt;.&lt;/p&gt;
</content><category term="Code"/><category term="sourcehut"/><category term="sr.ht"/><category term="Go"/><category term="Golang"/><category term="OpenTofu"/><category term="Terraform"/><category term="OpenSource"/><category term="Bugfix"/></entry><entry><title>OpenTofu based management of my git repositories</title><link href="https://dominik.wombacher.cc/posts/opentofu-based-management-of-my-git-repositories.html" rel="alternate"/><published>2025-01-13T00:00:00+01:00</published><updated>2025-01-13T00:00:00+01:00</updated><author><name>Dominik Wombacher</name></author><id>tag:dominik.wombacher.cc,2025-01-13:/posts/opentofu-based-management-of-my-git-repositories.html</id><summary type="html">&lt;!-- SPDX-FileCopyrightText: 2025 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;Yesterday I've completed the migration to
&lt;a class="reference external" href="https://git.sr.ht/~wombelix/git-repo-mgmt"&gt;git-repo-mgmt&lt;/a&gt;.
It's an OpenTofu based management of my git repositories at
Sourcehut with mirrors at Codeberg, Gitlab and GitHub.&lt;/p&gt;
&lt;p&gt;I was tired to manually  ... &lt;a class="read-more" href="/posts/opentofu-based-management-of-my-git-repositories.html"&gt; [read more]&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;!-- SPDX-FileCopyrightText: 2025 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;Yesterday I've completed the migration to
&lt;a class="reference external" href="https://git.sr.ht/~wombelix/git-repo-mgmt"&gt;git-repo-mgmt&lt;/a&gt;.
It's an OpenTofu based management of my git repositories at
Sourcehut with mirrors at Codeberg, Gitlab and GitHub.&lt;/p&gt;
&lt;p&gt;I was tired to manually create repos across four platforms.
Now it takes me seconds and a couple lines of code to do it, for example:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
# SPDX-FileCopyrightText: 2024 Dominik Wombacher &amp;lt;dominik&amp;#64;wombacher.cc&amp;gt;
#
# SPDX-License-Identifier: MIT

module &amp;quot;git-repo-mgmt&amp;quot; {
  source      = &amp;quot;./modules/repos&amp;quot;
  repo_name   = &amp;quot;git-repo-mgmt&amp;quot;
  description = &amp;quot;OpenTofu based management of my git repositories&amp;quot;
}

&lt;/pre&gt;
&lt;p&gt;The heart of the solution is a self written
&lt;a class="reference external" href="https://git.sr.ht/~wombelix/git-repo-mgmt/tree/main/item/modules/repos"&gt;OpenTofu / Terraform module&lt;/a&gt;
that does all the heavy lifting. It uses the
&lt;a class="reference external" href="https://dominik.wombacher.cc/posts/release-sourcehut-srht-opentofu-terraform-provider-and-go-library.html"&gt;sourcehut OpenTofu / Terraform provider&lt;/a&gt;
that I recently publish and leverages
&lt;a class="reference external" href="https://dominik.wombacher.cc/posts/opentofu-state-and-plan-encryption-with-aws-kms.html"&gt;AWS KMS for OpenTofu State and Plan Encryption&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On every push, &lt;a class="reference external" href="https://builds.sr.ht"&gt;builds.sr.ht&lt;/a&gt; is triggered and runs the &lt;code&gt;mirror&lt;/code&gt;, &lt;code&gt;setup&lt;/code&gt;, &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;plan&lt;/code&gt;
and &lt;code&gt;apply&lt;/code&gt; phases as defined in &lt;a class="reference external" href="https://git.sr.ht/~wombelix/git-repo-mgmt/tree/main/item/.build.yml"&gt;.build.yml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The overall workflow looks like this:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
git push
         &amp;gt; git.sr.ht
                     &amp;gt; builds.sr.ht
                                    &amp;gt; tofu apply
                                                 &amp;gt; sr.ht
                                                 &amp;gt; codeberg.org
                                                 &amp;gt; github.com
                                                 &amp;gt; gitlab.com

&lt;/pre&gt;
&lt;p&gt;I'm very satisfied with the result, this makes things so much easier.&lt;/p&gt;
</content><category term="Code"/><category term="OpenTofu"/><category term="Git"/><category term="OpenSource"/><category term="Automation"/><category term="AWS"/><category term="sr.ht"/><category term="sourcehut"/><category term="GitHub"/><category term="Gitlab"/><category term="Codeberg"/></entry><entry><title>Release: sourcehut (sr.ht) OpenTofu / Terraform provider and Go library</title><link href="https://dominik.wombacher.cc/posts/release-sourcehut-srht-opentofu-terraform-provider-and-go-library.html" rel="alternate"/><published>2024-12-28T00:00:00+01:00</published><updated>2024-12-28T00:00:00+01:00</updated><author><name>Dominik Wombacher</name></author><id>tag:dominik.wombacher.cc,2024-12-28:/posts/release-sourcehut-srht-opentofu-terraform-provider-and-go-library.html</id><summary type="html">&lt;!-- SPDX-FileCopyrightText: 2024 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;Today I released &lt;a class="reference external" href="https://git.sr.ht/~wombelix/terraform-provider-sourcehut"&gt;terraform-provider-sourcehut&lt;/a&gt;
and the related Go library &lt;a class="reference external" href="https://git.sr.ht/~wombelix/sourcehut-go"&gt;sourcehut-go&lt;/a&gt; into the wild.
The majority of code is licensed under &lt;code&gt;BSD-2-Clause&lt;/code&gt;.
The provider is available in the &lt;a class="reference external" href="https://search.opentofu.org/provider/wombelix/sourcehut/latest"&gt;OpenTofu&lt;/a&gt;
and &lt;a class="reference external" href="https://registry.terraform.io/providers/wombelix/sourcehut/latest"&gt;Terraform  ... &lt;/a&gt;&lt;a class="read-more" href="/posts/release-sourcehut-srht-opentofu-terraform-provider-and-go-library.html"&gt; [read more]&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;!-- SPDX-FileCopyrightText: 2024 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;Today I released &lt;a class="reference external" href="https://git.sr.ht/~wombelix/terraform-provider-sourcehut"&gt;terraform-provider-sourcehut&lt;/a&gt;
and the related Go library &lt;a class="reference external" href="https://git.sr.ht/~wombelix/sourcehut-go"&gt;sourcehut-go&lt;/a&gt; into the wild.
The majority of code is licensed under &lt;code&gt;BSD-2-Clause&lt;/code&gt;.
The provider is available in the &lt;a class="reference external" href="https://search.opentofu.org/provider/wombelix/sourcehut/latest"&gt;OpenTofu&lt;/a&gt;
and &lt;a class="reference external" href="https://registry.terraform.io/providers/wombelix/sourcehut/latest"&gt;Terraform&lt;/a&gt; registry.
The online version of the Documentation can be found there as well.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sourcehut-go&lt;/code&gt; is a Go SDK for accessing the sourcehut legacy REST API with oauth personal access tokens
created via &lt;a class="reference external" href="https://meta.sr.ht/oauth"&gt;meta.sr.ht/oauth&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Both projects are based on the work of &lt;a class="reference external" href="https://codeberg.org/SamWhited"&gt;Sam Whited&lt;/a&gt; who archived
the former code base on August 22, 2022.&lt;/p&gt;
&lt;p&gt;My motivation to improve and release it:
I plan to move my git repository management to OpenTofu.
Providers for my usual mirror targets GitHub, Gitlab and GitLab are available.
But there was no functional and published provider for sourcehut (sr.ht).
Which I use as my primary code hosting and build platform.&lt;/p&gt;
&lt;p&gt;Now that the library and provider are in a working state,
I can continue to work on the actual project :D&lt;/p&gt;
</content><category term="Code"/><category term="sourcehut"/><category term="sr.ht"/><category term="Go"/><category term="Golang"/><category term="OpenTofu"/><category term="Terraform"/><category term="OpenSource"/></entry><entry><title>Git repos moved to Sourcehut, with mirrors on Codeberg, GitLab and GitHub</title><link href="https://dominik.wombacher.cc/posts/git-repos-moved-to-sourcehut-with-mirrors-on-codeberg-gitlab-and-github.html" rel="alternate"/><published>2023-10-14T00:00:00+02:00</published><updated>2023-10-14T00:00:00+02:00</updated><author><name>Dominik Wombacher</name></author><id>tag:dominik.wombacher.cc,2023-10-14:/posts/git-repos-moved-to-sourcehut-with-mirrors-on-codeberg-gitlab-and-github.html</id><summary type="html">&lt;!-- SPDX-FileCopyrightText: 2023 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;When I &lt;a class="reference external" href="https://dominik.wombacher.cc/posts/website-migration-and-temporary-shutdown-of-onion-service.html"&gt;moved from a VPS to classic webhosting&lt;/a&gt;
I had to shutdown my self-hosted git repos as well. I had &lt;a class="reference external" href="https://sourcehut.org"&gt;Sourcehut&lt;/a&gt; on my list for years and decided it's  ... &lt;a class="read-more" href="/posts/git-repos-moved-to-sourcehut-with-mirrors-on-codeberg-gitlab-and-github.html"&gt; [read more]&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;!-- SPDX-FileCopyrightText: 2023 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;When I &lt;a class="reference external" href="https://dominik.wombacher.cc/posts/website-migration-and-temporary-shutdown-of-onion-service.html"&gt;moved from a VPS to classic webhosting&lt;/a&gt;
I had to shutdown my self-hosted git repos as well. I had &lt;a class="reference external" href="https://sourcehut.org"&gt;Sourcehut&lt;/a&gt; on my list for years and decided it's finally
time to test it. If you are used to (bloated) platforms like GitHub or GitLab, then Sourcehut is kind of shocking, in a positive way.
Pure HTML, no JavaScript, every feature (git repos, docs, build service, wiki ect.) is a widely independent micro-service with it's own subdomain.&lt;/p&gt;
&lt;p&gt;I really liked it and decided to go with a paid account, right now &lt;a class="reference external" href="https://sr.ht"&gt;sr.ht&lt;/a&gt; is in alpha state and payment is optional.
But alone the very nice build system and a fast loading page without tracking is more than worth it!&lt;/p&gt;
&lt;p&gt;From now on, &lt;a class="reference external" href="https://dominik.wombacher.cc/~git/"&gt;~git/&lt;/a&gt; redirects to &lt;a class="reference external" href="https://git.sr.ht/~wombelix/"&gt;git.sr.ht/~wombelix/&lt;/a&gt;, for
better visibility, I decided to also mirror to &lt;a class="reference external" href="https://codeberg.org/wombelix"&gt;codeberg.org/wombelix&lt;/a&gt;,
&lt;a class="reference external" href="https://gitlab.com/wombelix"&gt;gitlab.com/wombelix&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/wombelix"&gt;github.com/wombelix&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I don't want to force someone to follow a specific process or be limited to a single platform, if you like my projects
and want to contribute, use whatever site and workflow you prefer to create an issue or pull/merge-request, or send me a good old Email :).&lt;/p&gt;
&lt;p&gt;If I should create a list or tracker on sr.ht and have a preferred process one day,
I will add it to the README and/or CONTRIBUTE file in my projects.&lt;/p&gt;
</content><category term="Code"/><category term="Git"/><category term="Sourcehut"/><category term="Codeberg"/><category term="GitLab"/><category term="GitHub"/></entry></feed>