diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..7a34087 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,49 @@ +name: build + +on: + push: + branches: [main] + workflow_dispatch: + +env: + REGISTRY: harbor.furynrage.com + IMAGE: harbor.furynrage.com/demo-app/app + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Zot + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Compute tag + id: tag + run: echo "sha=$(echo ${{ github.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT + + - name: Build & push + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/arm64 + push: true + tags: | + ${{ env.IMAGE }}:${{ steps.tag.outputs.sha }} + ${{ env.IMAGE }}:latest + + - name: Trivy scan + uses: aquasecurity/trivy-action@0.24.0 + with: + image-ref: ${{ env.IMAGE }}:${{ steps.tag.outputs.sha }} + format: table + severity: CRITICAL,HIGH + exit-code: '0' # для демо не падаем, только репорт diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f2e023c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:1.22-alpine AS build +WORKDIR /src +COPY go.mod ./ +RUN go mod download +COPY *.go ./ +RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o /out/app . + +FROM gcr.io/distroless/static-debian12:nonroot +COPY --from=build /out/app /app +EXPOSE 8080 +USER nonroot +ENTRYPOINT ["/app"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..0fa7da6 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# demo-app (template для Gitea repo) + +Это template-копия. На Gitea Actions нужно работать в **Gitea**, поэтому: + +1. В Gitea (https://git.furynrage.com) создай repo `admin/demo-app` (private или public). +2. Локально: + ```bash + mkdir ~/demo-app-gitea && cd ~/demo-app-gitea + git init + cp -r ~/Desktop/Personal/developer-platform/apps/demo-app/. . + git add . && git commit -m "init" + git remote add origin https://git.furynrage.com/admin/demo-app.git + git push -u origin main + ``` + (basic auth — admin + пароль из `.secrets-gitea-admin.txt`) +3. В Gitea → Settings → Secrets and Variables → Actions добавь: + - `REGISTRY_USER` = `ci-pusher` + - `REGISTRY_PASSWORD` = из `.secrets-zot.txt` +4. Push в `main` → workflow `.gitea/workflows/build.yml` запустится автоматически. + +Результат: +- образ `harbor.furynrage.com/demo-app/app:` появится в Zot UI +- Trivy scan покажется в logs job'а +- ArgoCD Image Updater подхватит новый тег и задеплоит в namespace `demo-app` diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..61fab64 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/furynrage/demo-app + +go 1.22 diff --git a/main.go b/main.go new file mode 100644 index 0000000..0de0ea7 --- /dev/null +++ b/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" + "os" +) + +var version = os.Getenv("APP_VERSION") + +type status struct { + Status string `json:"status"` + Version string `json:"version"` +} + +func main() { + if version == "" { + version = "dev" + } + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(status{Status: "ok", Version: version}) + }) + + http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("ok")) + }) + + addr := ":8080" + log.Printf("listening on %s, version=%s", addr, version) + log.Fatal(http.ListenAndServe(addr, nil)) +}