use as gitea action
Publish Action Image / build (push) Successful in 31s

This commit is contained in:
2026-06-29 16:01:01 +10:00
parent 4ee1b9e13c
commit 9adb5780f2
6 changed files with 236 additions and 248 deletions
+6
View File
@@ -2,6 +2,7 @@ package config
import (
"fmt"
"os"
"strings"
"kforge/pkg/interpolate"
@@ -306,6 +307,11 @@ func ResolveEnvironment(cfg *KforgeConfig, envKey string) (ResolvedEnvironment,
if imageTag == "" {
imageTag = DefaultImageTag
}
// Allow the action entrypoint (or CI) to override the image tag at generate
// time without modifying kforge.yml (e.g. KFORGE_IMAGE_TAG=abc1234).
if override := os.Getenv("KFORGE_IMAGE_TAG"); override != "" {
imageTag = override
}
image := registry.URL + "/" + registry.Repository + ":" + imageTag
replicas := *cfg.Defaults.Replicas
+6
View File
@@ -14,6 +14,12 @@ type KforgeConfig struct {
Infrastructure InfrastructureConfig `yaml:"infrastructure"`
Preview PreviewConfig `yaml:"preview,omitempty"`
Environments map[string]EnvironmentConfig `yaml:"environments"`
// ActionRef is the Gitea Actions reference to this kforge installation
// (e.g. "gitea.example.com/infra/kforge@main"). When set, kforge gitea-actions
// and kforge gitea-preview generate workflows that call kforge as a reusable
// action step instead of installing and running kforge inline.
ActionRef string `yaml:"action_ref,omitempty"`
}
// ------------------------------------------------------------
+115 -53
View File
@@ -74,10 +74,6 @@ func writeDeployJobs(b *strings.Builder, cfg *config.KforgeConfig, opts GiteaAct
"with": map[string]any{"fetch-depth": 0},
})
writeStep(b, "Create short commit hash", map[string]any{
"run": `echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV`,
})
writeStep(b, "Login to registry", map[string]any{
"uses": "docker/login-action@v2",
"with": map[string]any{
@@ -101,6 +97,39 @@ func writeDeployJobs(b *strings.Builder, cfg *config.KforgeConfig, opts GiteaAct
},
})
if cfg.ActionRef != "" {
writeActionDeploySteps(b, cfg, opts)
} else {
writeInlineDeploySteps(b, cfg, opts)
}
}
// writeActionDeploySteps emits one `uses: action_ref` step per environment.
func writeActionDeploySteps(b *strings.Builder, cfg *config.KforgeConfig, opts GiteaActionsOptions) {
for _, envKey := range opts.Environments {
env, err := config.ResolveEnvironment(cfg, envKey)
if err != nil {
continue
}
label := strings.Title(envKey) //nolint:staticcheck
writeStep(b, fmt.Sprintf("Deploy (%s)", label), map[string]any{
"uses": cfg.ActionRef,
"with": map[string]any{
"command": "deploy",
"env": envKey,
"namespace": env.Namespace,
},
"env": actionEnv(),
})
}
}
// writeInlineDeploySteps emits the classic multi-step inline approach.
func writeInlineDeploySteps(b *strings.Builder, cfg *config.KforgeConfig, opts GiteaActionsOptions) {
writeStep(b, "Create short commit hash", map[string]any{
"run": `echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV`,
})
writeStep(b, "Install kforge", map[string]any{
"run": "KFORGE_VERSION=\"latest\"\ncurl -fsSL \"https://kforge/releases/download/${KFORGE_VERSION}/kforge-linux-amd64\" -o /usr/local/bin/kforge\nchmod +x /usr/local/bin/kforge",
})
@@ -244,60 +273,82 @@ func GeneratePreviewActions(cfg *config.KforgeConfig) (string, error) {
},
})
writeStep(&b, "Install kforge", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"run": "KFORGE_VERSION=\"latest\"\ncurl -fsSL \"https://kforge/releases/download/${KFORGE_VERSION}/kforge-linux-amd64\" -o /usr/local/bin/kforge\nchmod +x /usr/local/bin/kforge",
})
if cfg.ActionRef != "" {
writeStep(&b, "Deploy preview", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"uses": cfg.ActionRef,
"with": map[string]any{
"command": "preview-up",
"pr_number": "${{ github.event.number }}",
"namespace_prefix": nsPrefix,
},
"env": actionEnv(),
})
writeStep(&b, "Apply preview secrets", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"run": "kforge secrets apply --pr-number ${{ github.event.number }}",
"env": giteaKubeEnv(),
})
writeStep(&b, "Destroy preview", map[string]any{
"if": "${{ github.event.action == 'closed' }}",
"uses": cfg.ActionRef,
"with": map[string]any{
"command": "preview-down",
"pr_number": "${{ github.event.number }}",
"namespace_prefix": nsPrefix,
},
"env": actionEnv(),
})
} else {
writeStep(&b, "Install kforge", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"run": "KFORGE_VERSION=\"latest\"\ncurl -fsSL \"https://kforge/releases/download/${KFORGE_VERSION}/kforge-linux-amd64\" -o /usr/local/bin/kforge\nchmod +x /usr/local/bin/kforge",
})
writeStep(&b, "Generate preview manifests", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"run": "kforge generate --pr-number ${{ github.event.number }} --output .kforge-out",
"env": map[string]any{
"KFORGE_NODE_IP": "${{ secrets.KFORGE_NODE_IP }}",
"PR_NUMBER": "${{ github.event.number }}",
},
})
writeStep(&b, "Apply preview secrets", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"run": "kforge secrets apply --pr-number ${{ github.event.number }}",
"env": giteaKubeEnv(),
})
writeStep(&b, "Apply preview manifests", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"uses": "actions-hub/kubectl@master",
"env": giteaKubeEnv(),
"with": map[string]any{
"args": fmt.Sprintf(
"apply -f .kforge-out/ --insecure-skip-tls-verify",
),
},
})
writeStep(&b, "Generate preview manifests", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"run": "kforge generate --pr-number ${{ github.event.number }} --output .kforge-out",
"env": map[string]any{
"KFORGE_NODE_IP": "${{ secrets.KFORGE_NODE_IP }}",
"PR_NUMBER": "${{ github.event.number }}",
},
})
writeStep(&b, "Wait for preview rollout", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"uses": "actions-hub/kubectl@master",
"env": giteaKubeEnv(),
"with": map[string]any{
"args": fmt.Sprintf(
"rollout status deployment -n %s-${{ github.event.number }} --timeout=120s --insecure-skip-tls-verify",
nsPrefix,
),
},
})
writeStep(&b, "Apply preview manifests", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"uses": "actions-hub/kubectl@master",
"env": giteaKubeEnv(),
"with": map[string]any{
"args": "apply -f .kforge-out/ --insecure-skip-tls-verify",
},
})
writeStep(&b, "Destroy preview namespace", map[string]any{
"if": "${{ github.event.action == 'closed' }}",
"uses": "actions-hub/kubectl@master",
"env": giteaKubeEnv(),
"with": map[string]any{
"args": fmt.Sprintf(
"delete namespace %s-${{ github.event.number }} --ignore-not-found --insecure-skip-tls-verify",
nsPrefix,
),
},
})
writeStep(&b, "Wait for preview rollout", map[string]any{
"if": "${{ github.event.action != 'closed' }}",
"uses": "actions-hub/kubectl@master",
"env": giteaKubeEnv(),
"with": map[string]any{
"args": fmt.Sprintf(
"rollout status deployment -n %s-${{ github.event.number }} --timeout=120s --insecure-skip-tls-verify",
nsPrefix,
),
},
})
writeStep(&b, "Destroy preview namespace", map[string]any{
"if": "${{ github.event.action == 'closed' }}",
"uses": "actions-hub/kubectl@master",
"env": giteaKubeEnv(),
"with": map[string]any{
"args": fmt.Sprintf(
"delete namespace %s-${{ github.event.number }} --ignore-not-found --insecure-skip-tls-verify",
nsPrefix,
),
},
})
}
return b.String(), nil
}
@@ -383,6 +434,17 @@ func giteaKubeEnv() map[string]any {
}
}
// actionEnv returns the combined env block for a kforge action step —
// kubectl auth plus the node IP for external-dns annotation resolution.
func actionEnv() map[string]any {
return map[string]any{
"KUBE_CERTIFICATE": "${{ secrets.KUBE_CERTIFICATE }}",
"KUBE_HOST": "${{ secrets.KUBE_HOST }}",
"KUBE_TOKEN": "${{ secrets.KUBE_TOKEN }}",
"KFORGE_NODE_IP": "${{ secrets.KFORGE_NODE_IP }}",
}
}
func mergeMaps(maps ...map[string]any) map[string]any {
result := map[string]any{}
for _, m := range maps {