Skip to content

Commit a97a856

Browse files
committed
feat: add gitea bootstrapper
1 parent 28971ed commit a97a856

File tree

5 files changed

+302
-0
lines changed

5 files changed

+302
-0
lines changed

cmd/flux/bootstrap_gitea.go

+275
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
/*
2+
Copyright 2023 The Flux authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
"time"
24+
25+
"github.com/fluxcd/pkg/git"
26+
"github.com/fluxcd/pkg/git/gogit"
27+
"github.com/spf13/cobra"
28+
29+
"github.com/fluxcd/flux2/v2/internal/flags"
30+
"github.com/fluxcd/flux2/v2/internal/utils"
31+
"github.com/fluxcd/flux2/v2/pkg/bootstrap"
32+
"github.com/fluxcd/flux2/v2/pkg/bootstrap/provider"
33+
"github.com/fluxcd/flux2/v2/pkg/manifestgen"
34+
"github.com/fluxcd/flux2/v2/pkg/manifestgen/install"
35+
"github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret"
36+
"github.com/fluxcd/flux2/v2/pkg/manifestgen/sync"
37+
)
38+
39+
var bootstrapGiteaCmd = &cobra.Command{
40+
Use: "gitea",
41+
Short: "Deploy Flux on a cluster connected to a Gitea repository",
42+
Long: `The bootstrap gitea command creates the Gitea repository if it doesn't exists and
43+
commits the Flux manifests to the specified branch.
44+
Then it configures the target cluster to synchronize with that repository.
45+
If the Flux components are present on the cluster,
46+
the bootstrap command will perform an upgrade if needed.`,
47+
Example: ` # Create a Gitea personal access token and export it as an env var
48+
export GITEA_TOKEN=<my-token>
49+
50+
# Run bootstrap for a private repository owned by a Gitea organization
51+
flux bootstrap gitea --owner=<organization> --repository=<repository name> --path=clusters/my-cluster
52+
53+
# Run bootstrap for a private repository and assign organization teams to it
54+
flux bootstrap gitea --owner=<organization> --repository=<repository name> --team=<team1 slug> --team=<team2 slug> --path=clusters/my-cluster
55+
56+
# Run bootstrap for a private repository and assign organization teams with their access level(e.g maintain, admin) to it
57+
flux bootstrap gitea --owner=<organization> --repository=<repository name> --team=<team1 slug>:<access-level> --path=clusters/my-cluster
58+
59+
# Run bootstrap for a public repository on a personal account
60+
flux bootstrap gitea --owner=<user> --repository=<repository name> --private=false --personal=true --path=clusters/my-cluster
61+
62+
# Run bootstrap for a private repository hosted on Gitea Enterprise using SSH auth
63+
flux bootstrap gitea --owner=<organization> --repository=<repository name> --hostname=<domain> --ssh-hostname=<domain> --path=clusters/my-cluster
64+
65+
# Run bootstrap for a private repository hosted on Gitea Enterprise using HTTPS auth
66+
flux bootstrap gitea --owner=<organization> --repository=<repository name> --hostname=<domain> --token-auth --path=clusters/my-cluster
67+
68+
# Run bootstrap for an existing repository with a branch named main
69+
flux bootstrap gitea --owner=<organization> --repository=<repository name> --branch=main --path=clusters/my-cluster`,
70+
RunE: bootstrapGiteaCmdRun,
71+
}
72+
73+
type giteaFlags struct {
74+
owner string
75+
repository string
76+
interval time.Duration
77+
personal bool
78+
private bool
79+
hostname string
80+
path flags.SafeRelativePath
81+
teams []string
82+
readWriteKey bool
83+
reconcile bool
84+
}
85+
86+
const (
87+
gtDefaultPermission = "maintain"
88+
gtDefaultDomain = "gitea.com"
89+
gtTokenEnvVar = "GITEA_TOKEN"
90+
)
91+
92+
var giteaArgs giteaFlags
93+
94+
func init() {
95+
bootstrapGiteaCmd.Flags().StringVar(&giteaArgs.owner, "owner", "", "Gitea user or organization name")
96+
bootstrapGiteaCmd.Flags().StringVar(&giteaArgs.repository, "repository", "", "Gitea repository name")
97+
bootstrapGiteaCmd.Flags().StringSliceVar(&giteaArgs.teams, "team", []string{}, "Gitea team and the access to be given to it(team:maintain). Defaults to maintainer access if no access level is specified (also accepts comma-separated values)")
98+
bootstrapGiteaCmd.Flags().BoolVar(&giteaArgs.personal, "personal", false, "if true, the owner is assumed to be a Gitea user; otherwise an org")
99+
bootstrapGiteaCmd.Flags().BoolVar(&giteaArgs.private, "private", true, "if true, the repository is setup or configured as private")
100+
bootstrapGiteaCmd.Flags().DurationVar(&giteaArgs.interval, "interval", time.Minute, "sync interval")
101+
bootstrapGiteaCmd.Flags().StringVar(&giteaArgs.hostname, "hostname", gtDefaultDomain, "Gitea hostname")
102+
bootstrapGiteaCmd.Flags().Var(&giteaArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path")
103+
bootstrapGiteaCmd.Flags().BoolVar(&giteaArgs.readWriteKey, "read-write-key", false, "if true, the deploy key is configured with read/write permissions")
104+
bootstrapGiteaCmd.Flags().BoolVar(&giteaArgs.reconcile, "reconcile", false, "if true, the configured options are also reconciled if the repository already exists")
105+
106+
bootstrapCmd.AddCommand(bootstrapGiteaCmd)
107+
}
108+
109+
func bootstrapGiteaCmdRun(cmd *cobra.Command, args []string) error {
110+
gtToken := os.Getenv(gtTokenEnvVar)
111+
if gtToken == "" {
112+
var err error
113+
gtToken, err = readPasswordFromStdin("Please enter your Gitea personal access token (PAT): ")
114+
if err != nil {
115+
return fmt.Errorf("could not read token: %w", err)
116+
}
117+
}
118+
119+
if err := bootstrapValidate(); err != nil {
120+
return err
121+
}
122+
123+
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
124+
defer cancel()
125+
126+
kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions)
127+
if err != nil {
128+
return err
129+
}
130+
131+
// Manifest base
132+
if ver, err := getVersion(bootstrapArgs.version); err != nil {
133+
return err
134+
} else {
135+
bootstrapArgs.version = ver
136+
}
137+
manifestsBase, err := buildEmbeddedManifestBase()
138+
if err != nil {
139+
return err
140+
}
141+
defer os.RemoveAll(manifestsBase)
142+
143+
var caBundle []byte
144+
if bootstrapArgs.caFile != "" {
145+
var err error
146+
caBundle, err = os.ReadFile(bootstrapArgs.caFile)
147+
if err != nil {
148+
return fmt.Errorf("unable to read TLS CA file: %w", err)
149+
}
150+
}
151+
// Build Gitea provider
152+
providerCfg := provider.Config{
153+
Provider: provider.GitProviderGitea,
154+
Hostname: giteaArgs.hostname,
155+
Token: gtToken,
156+
CaBundle: caBundle,
157+
}
158+
providerClient, err := provider.BuildGitProvider(providerCfg)
159+
if err != nil {
160+
return err
161+
}
162+
163+
tmpDir, err := manifestgen.MkdirTempAbs("", "flux-bootstrap-")
164+
if err != nil {
165+
return fmt.Errorf("failed to create temporary working dir: %w", err)
166+
}
167+
defer os.RemoveAll(tmpDir)
168+
169+
clientOpts := []gogit.ClientOption{gogit.WithDiskStorage(), gogit.WithFallbackToDefaultKnownHosts()}
170+
gitClient, err := gogit.NewClient(tmpDir, &git.AuthOptions{
171+
Transport: git.HTTPS,
172+
Username: giteaArgs.owner,
173+
Password: gtToken,
174+
CAFile: caBundle,
175+
}, clientOpts...)
176+
if err != nil {
177+
return fmt.Errorf("failed to create a Git client: %w", err)
178+
}
179+
180+
// Install manifest config
181+
installOptions := install.Options{
182+
BaseURL: rootArgs.defaults.BaseURL,
183+
Version: bootstrapArgs.version,
184+
Namespace: *kubeconfigArgs.Namespace,
185+
Components: bootstrapComponents(),
186+
Registry: bootstrapArgs.registry,
187+
ImagePullSecret: bootstrapArgs.imagePullSecret,
188+
WatchAllNamespaces: bootstrapArgs.watchAllNamespaces,
189+
NetworkPolicy: bootstrapArgs.networkPolicy,
190+
LogLevel: bootstrapArgs.logLevel.String(),
191+
NotificationController: rootArgs.defaults.NotificationController,
192+
ManifestFile: rootArgs.defaults.ManifestFile,
193+
Timeout: rootArgs.timeout,
194+
TargetPath: giteaArgs.path.ToSlash(),
195+
ClusterDomain: bootstrapArgs.clusterDomain,
196+
TolerationKeys: bootstrapArgs.tolerationKeys,
197+
}
198+
if customBaseURL := bootstrapArgs.manifestsPath; customBaseURL != "" {
199+
installOptions.BaseURL = customBaseURL
200+
}
201+
202+
// Source generation and secret config
203+
secretOpts := sourcesecret.Options{
204+
Name: bootstrapArgs.secretName,
205+
Namespace: *kubeconfigArgs.Namespace,
206+
TargetPath: giteaArgs.path.ToSlash(),
207+
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
208+
}
209+
if bootstrapArgs.tokenAuth {
210+
secretOpts.Username = "git"
211+
secretOpts.Password = gtToken
212+
secretOpts.CAFile = caBundle
213+
} else {
214+
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
215+
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
216+
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
217+
218+
secretOpts.SSHHostname = giteaArgs.hostname
219+
if bootstrapArgs.sshHostname != "" {
220+
secretOpts.SSHHostname = bootstrapArgs.sshHostname
221+
}
222+
}
223+
224+
// Sync manifest config
225+
syncOpts := sync.Options{
226+
Interval: giteaArgs.interval,
227+
Name: *kubeconfigArgs.Namespace,
228+
Namespace: *kubeconfigArgs.Namespace,
229+
Branch: bootstrapArgs.branch,
230+
Secret: bootstrapArgs.secretName,
231+
TargetPath: giteaArgs.path.ToSlash(),
232+
ManifestFile: sync.MakeDefaultOptions().ManifestFile,
233+
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
234+
}
235+
236+
entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath)
237+
if err != nil {
238+
return err
239+
}
240+
241+
// Bootstrap config
242+
bootstrapOpts := []bootstrap.GitProviderOption{
243+
bootstrap.WithProviderRepository(giteaArgs.owner, giteaArgs.repository, giteaArgs.personal),
244+
bootstrap.WithBranch(bootstrapArgs.branch),
245+
bootstrap.WithBootstrapTransportType("https"),
246+
bootstrap.WithSignature(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
247+
bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
248+
bootstrap.WithProviderTeamPermissions(mapTeamSlice(giteaArgs.teams, gtDefaultPermission)),
249+
bootstrap.WithReadWriteKeyPermissions(giteaArgs.readWriteKey),
250+
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
251+
bootstrap.WithLogger(logger),
252+
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
253+
}
254+
if bootstrapArgs.sshHostname != "" {
255+
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
256+
}
257+
if bootstrapArgs.tokenAuth {
258+
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSyncTransportType("https"))
259+
}
260+
if !giteaArgs.private {
261+
bootstrapOpts = append(bootstrapOpts, bootstrap.WithProviderRepositoryConfig("", "", "public"))
262+
}
263+
if giteaArgs.reconcile {
264+
bootstrapOpts = append(bootstrapOpts, bootstrap.WithReconcile())
265+
}
266+
267+
// Setup bootstrapper with constructed configs
268+
b, err := bootstrap.NewGitProviderBootstrapper(gitClient, providerClient, kubeClient, bootstrapOpts...)
269+
if err != nil {
270+
return err
271+
}
272+
273+
// Run
274+
return bootstrap.Run(ctx, b, manifestsBase, installOptions, secretOpts, syncOpts, rootArgs.pollInterval, rootArgs.timeout)
275+
}

go.mod

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ require (
6363
)
6464

6565
require (
66+
code.gitea.io/sdk/gitea v0.16.0 // indirect
6667
dario.cat/mergo v1.0.0 // indirect
6768
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 // indirect
6869
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1 // indirect
@@ -95,6 +96,7 @@ require (
9596
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
9697
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
9798
github.com/davecgh/go-spew v1.1.1 // indirect
99+
github.com/davidmz/go-pageant v1.0.2 // indirect
98100
github.com/docker/cli v24.0.0+incompatible // indirect
99101
github.com/docker/distribution v2.8.2+incompatible // indirect
100102
github.com/docker/docker v24.0.7+incompatible // indirect
@@ -114,6 +116,7 @@ require (
114116
github.com/fluxcd/pkg/apis/kustomize v1.1.1 // indirect
115117
github.com/fsnotify/fsnotify v1.6.0 // indirect
116118
github.com/go-errors/errors v1.4.2 // indirect
119+
github.com/go-fed/httpsig v1.1.0 // indirect
117120
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
118121
github.com/go-git/go-billy/v5 v5.5.0 // indirect
119122
github.com/go-openapi/jsonpointer v0.19.6 // indirect
@@ -141,6 +144,7 @@ require (
141144
github.com/hashicorp/errwrap v1.1.0 // indirect
142145
github.com/hashicorp/go-multierror v1.1.1 // indirect
143146
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
147+
github.com/hashicorp/go-version v1.5.0 // indirect
144148
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect
145149
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
146150
github.com/imdario/mergo v0.3.15 // indirect

go.sum

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
22
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3+
code.gitea.io/sdk/gitea v0.16.0 h1:gAfssETO1Hv9QbE+/nhWu7EjoFQYKt6kPoyDytQgw00=
4+
code.gitea.io/sdk/gitea v0.16.0/go.mod h1:ndkDk99BnfiUCCYEUhpNzi0lpmApXlwRFqClBlOlEBg=
35
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
46
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
57
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
@@ -97,6 +99,8 @@ github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG
9799
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
98100
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
99101
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
102+
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
103+
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
100104
github.com/distribution/distribution/v3 v3.0.0-20230823142118-4f7424c8eb41 h1:vlGNYFw1NB27Gk5tIwJpiog1Ti6FKOUI+DoFZKoCDZo=
101105
github.com/distribution/distribution/v3 v3.0.0-20230823142118-4f7424c8eb41/go.mod h1:WREzLx07iIFUGvbm6tBoqGt40zOC3whiM1qkcWOMFrs=
102106
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
@@ -190,6 +194,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
190194
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
191195
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
192196
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
197+
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
198+
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
193199
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
194200
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
195201
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
@@ -301,6 +307,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
301307
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
302308
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
303309
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
310+
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
311+
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
304312
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=
305313
github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=
306314
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
@@ -506,7 +514,9 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
506514
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
507515
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
508516
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
517+
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
509518
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
519+
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
510520
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
511521
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
512522
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=

pkg/bootstrap/provider/factory.go

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package provider
1919
import (
2020
"fmt"
2121

22+
"github.com/fluxcd/go-git-providers/gitea"
2223
"github.com/fluxcd/go-git-providers/github"
2324
"github.com/fluxcd/go-git-providers/gitlab"
2425
"github.com/fluxcd/go-git-providers/gitprovider"
@@ -45,6 +46,17 @@ func BuildGitProvider(config Config) (gitprovider.Client, error) {
4546
if client, err = github.NewClient(opts...); err != nil {
4647
return nil, err
4748
}
49+
case GitProviderGitea:
50+
opts := []gitprovider.ClientOption{}
51+
if config.Hostname != "" {
52+
opts = append(opts, gitprovider.WithDomain(config.Hostname))
53+
}
54+
if config.CaBundle != nil {
55+
opts = append(opts, gitprovider.WithCustomCAPostChainTransportHook(config.CaBundle))
56+
}
57+
if client, err = gitea.NewClient(config.Token, opts...); err != nil {
58+
return nil, err
59+
}
4860
case GitProviderGitLab:
4961
opts := []gitprovider.ClientOption{
5062
gitprovider.WithConditionalRequests(true),

pkg/bootstrap/provider/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type GitProvider string
2121

2222
const (
2323
GitProviderGitHub GitProvider = "github"
24+
GitProviderGitea GitProvider = "gitea"
2425
GitProviderGitLab GitProvider = "gitlab"
2526
GitProviderStash GitProvider = "stash"
2627
)

0 commit comments

Comments
 (0)