Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 86 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,35 @@ concurrency:
cancel-in-progress: true

env:
GO_VERSION: "1.25"
GO_VERSION: "1.25.10"
BUN_VERSION: "1.2.21"

jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
cache-dependency-path: backend/go.sum

- name: govulncheck
working-directory: backend
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...

- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build:
runs-on: ubuntu-latest
steps:
Expand All @@ -39,6 +64,8 @@ jobs:
cd backend
go mod download
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.0.2
go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.31.1
sqlc diff || (echo "sqlc generated code is out of date. Run 'make sqlc' to regenerate." && exit 1)
go vet ./...
golangci-lint run ./...
go test ./... -race -count=1
Expand All @@ -51,3 +78,61 @@ jobs:
bun run vue-tsc --noEmit
bun run test
bun run build

e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: ${{ env.BUN_VERSION }}
cache: true

- name: Install dependencies
working-directory: frontend
run: |
bun install --frozen-lockfile
bunx --bun playwright install --with-deps chromium

- name: Run E2E tests
working-directory: frontend
run: bunx --bun playwright test --config playwright.config.ts

- name: Upload report
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: frontend/playwright-report/

- name: Dump container logs
if: failure()
run: docker compose logs --no-color --tail=200

- name: Cleanup
if: always()
run: docker compose down -v

release:
needs: [security, build, e2e]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install semantic-release
run: npm install -g semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/github

- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: semantic-release
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ backend/uploads/
backend/tmp/
build/

# Frontend
# Node
node_modules/
frontend/node_modules/
frontend/dist/
frontend/.env.local
Expand All @@ -23,3 +24,8 @@ frontend/.env.local

# OS
.DS_Store

# E2E
e2e/test-results/
e2e/playwright-report/

8 changes: 8 additions & 0 deletions .releaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/github"
]
}
22 changes: 20 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
fmt fmt-backend fmt-frontend \
typecheck tidy vet \
deadcode deadcode-backend deadcode-frontend \
check ci clean help
vulncheck swagger sqlc e2e check ci clean help

# === Local Development (tudo via Docker, 1 porta) ===

Expand Down Expand Up @@ -117,6 +117,24 @@ fmt-frontend:
vet:
cd backend && go vet ./...

## Vulnerability scan (Go dependencies)
vulncheck:
cd backend && go run golang.org/x/vuln/cmd/govulncheck@latest ./...

## Generate OpenAPI/Swagger docs
swagger:
cd backend && go run github.com/swaggo/swag/cmd/swag@latest init \
--generalInfo cmd/server/main.go \
--output docs/swagger \
--parseDependency --parseDepth 2

## Generate SQL code from queries
sqlc:
cd backend && sqlc generate

e2e:
cd frontend && bun run e2e

tidy:
cd backend && go mod tidy

Expand All @@ -141,7 +159,7 @@ deadcode-frontend:
cd frontend && bunx --bun depcheck || true

## Aggregate checks used locally and in CI
check: fmt-backend lint test
check: fmt-backend lint sqlc test

ci: lint test
@echo "CI checks passed."
Expand Down
32 changes: 32 additions & 0 deletions backend/cmd/server/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
// Blueprint API — Full-stack starter kit
//
// @title Blueprint API
// @version 1.0.0
// @description Full-stack starter kit with Go + Fiber backend and Vue 3 frontend.
// @termsOfService https://github.com/afa/blueprint

// @contact.name Blueprint Maintainer
// @contact.url https://github.com/afa/blueprint

// @license.name MIT
// @license.url https://github.com/afa/blueprint/blob/main/LICENSE

// @host localhost:8080
// @BasePath /api/v1

// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description JWT token (Bearer <token>)
package main

import (
Expand All @@ -7,6 +27,8 @@ import (
"log"
"time"

swaggerdocs "github.com/afa/blueprint/backend/docs/swagger"
"github.com/gofiber/contrib/swagger"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/logger"
Expand Down Expand Up @@ -98,6 +120,16 @@ func main() {
return nil
})

// Swagger UI (non-production only)
if cfg.Env != "production" {
app.Get("/swagger/*", swagger.New(swagger.Config{
BasePath: "/",
FilePath: "swagger.json",
FileContent: []byte(swaggerdocs.SwaggerInfo.ReadDoc()),
Path: "/swagger",
}))
}

// Health check
app.Get("/healthz", func(c *fiber.Ctx) error {
if err := pool.Ping(c.Context()); err != nil {
Expand Down
Loading
Loading