diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd39abb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Git +.git +.gitignore + +# CI/CD +.github + +# Documentation +*.md +!README.md + +# Build artifacts +bin/ +dist/ +build/ +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test artifacts +*.test +*.out +coverage.out +coverage.html + +# IDE +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Go workspace +go.work +go.work.sum + +# Taskfile +Taskfile.yml diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json new file mode 100644 index 0000000..e18ee07 --- /dev/null +++ b/.github/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.0" +} diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 0000000..ccca081 --- /dev/null +++ b/.github/release-please-config.json @@ -0,0 +1,22 @@ +{ + "packages": { + ".": {} + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "go", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "changelog-sections": [ + { "type": "feat", "section": "Features" }, + { "type": "fix", "section": "Bug Fixes" }, + { "type": "perf", "section": "Performance Improvements" }, + { "type": "revert", "section": "Reverts" }, + { "type": "docs", "section": "Documentation" }, + { "type": "style", "section": "Styles", "hidden": true }, + { "type": "chore", "section": "Miscellaneous Chores", "hidden": true }, + { "type": "refactor", "section": "Code Refactoring", "hidden": true }, + { "type": "test", "section": "Tests", "hidden": true }, + { "type": "build", "section": "Build System", "hidden": true }, + { "type": "ci", "section": "Continuous Integration", "hidden": true } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..132e7bd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.24' + + - name: golangci-lint + uses: golangci/golangci-lint-action@v4 + with: + version: latest + + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.24 + + - name: Run tests + run: go test -v -race -coverprofile=coverage.out ./... + + - name: Upload coverage + uses: codecov/codecov-action@v4 + with: + file: ./coverage.out + fail_ci_if_error: false + + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.24' + + - name: Build + run: go build -v ./cmd/smallflow + + - name: Build Docker image + run: docker build -t smallflow:latest . diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..abc9592 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,52 @@ +name: Release Please + +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - name: Run release-please + uses: google-github-actions/release-please-action@v4 + id: release + with: + release-type: go + package-name: smallflow + + - name: Checkout code + if: ${{ steps.release.outputs.release_created }} + uses: actions/checkout@v4 + + - name: Set up Go + if: ${{ steps.release.outputs.release_created }} + uses: actions/setup-go@v5 + with: + go-version: '1.24' + + - name: Build binaries + if: ${{ steps.release.outputs.release_created }} + run: | + GOOS=linux GOARCH=amd64 go build -o smallflow-linux-amd64 ./cmd/smallflow + GOOS=linux GOARCH=arm64 go build -o smallflow-linux-arm64 ./cmd/smallflow + GOOS=darwin GOARCH=amd64 go build -o smallflow-darwin-amd64 ./cmd/smallflow + GOOS=darwin GOARCH=arm64 go build -o smallflow-darwin-arm64 ./cmd/smallflow + GOOS=windows GOARCH=amd64 go build -o smallflow-windows-amd64.exe ./cmd/smallflow + + - name: Upload Release Artifacts + if: ${{ steps.release.outputs.release_created }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release upload ${{ steps.release.outputs.tag_name }} \ + smallflow-linux-amd64 \ + smallflow-linux-arm64 \ + smallflow-darwin-amd64 \ + smallflow-darwin-arm64 \ + smallflow-windows-amd64.exe diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a70b53 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool +*.out + +# Dependency directories +vendor/ + +# Go workspace file +go.work + +# Build artifacts +/bin/ +/dist/ +/build/ + +# IDE specific files +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS specific files +.DS_Store +Thumbs.db diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..2676388 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,31 @@ +linters: + enable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - unused + - gofmt + - goimports + - misspell + - unconvert + - unparam + - whitespace + +linters-settings: + errcheck: + check-type-assertions: true + check-blank: true + + govet: + check-shadowing: true + +run: + timeout: 5m + tests: true + +issues: + exclude-use-default: false + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d19bfe3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# Build stage +FROM golang:1.24-alpine AS builder + +# Install build dependencies +RUN apk add --no-cache git make ca-certificates + +# Set working directory +WORKDIR /app + +# Copy go mod files +COPY go.mod go.sum* ./ + +# Download dependencies +RUN go mod download + +# Copy source code +COPY . . + +# Build the application +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -trimpath -o /bin/smallflow ./cmd/smallflow + +# Final stage +FROM alpine:3.20 + +# Install runtime dependencies +RUN apk --no-cache add ca-certificates tzdata + +# Create non-root user +RUN addgroup -g 1000 smallflow && \ + adduser -D -u 1000 -G smallflow smallflow + +# Set working directory +WORKDIR /home/smallflow + +# Copy binary from builder +COPY --from=builder /bin/smallflow /usr/local/bin/smallflow + +# Change ownership +RUN chown -R smallflow:smallflow /home/smallflow + +# Switch to non-root user +USER smallflow + +# Run the application +ENTRYPOINT ["smallflow"] diff --git a/README.md b/README.md index 1b23834..4d944a2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # smallflow -Build, run, and observe workflows without the overhead +Build, run, and observe workflows without the overhead! + +SmallFlow is a lightweight, workflow orchestration engine written in Go. +Designed for simplicity, auditability, and extensibility, SmallFlow helps you build, run, and observe workflows without the overhead of heavyweight platforms. + diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..faa2d7c --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,71 @@ +version: '3' + +vars: + BINARY_NAME: smallflow + MAIN_PATH: ./cmd/smallflow + +tasks: + default: + desc: Show available tasks + cmds: + - task --list + + build: + desc: Build the binary + cmds: + - go build -o bin/{{.BINARY_NAME}} {{.MAIN_PATH}} + sources: + - "**/*.go" + generates: + - bin/{{.BINARY_NAME}} + + run: + desc: Run the application + cmds: + - task: build + - ./bin/{{.BINARY_NAME}} + + test: + desc: Run tests + cmds: + - go test -v -race -coverprofile=coverage.out ./... + + test-coverage: + desc: Run tests with coverage report + cmds: + - go test -v -race -coverprofile=coverage.out ./... + - go tool cover -html=coverage.out -o coverage.html + + lint: + desc: Run linter + cmds: + - golangci-lint run ./... + + fmt: + desc: Format code + cmds: + - go fmt ./... + + vet: + desc: Run go vet + cmds: + - go vet ./... + + tidy: + desc: Tidy go modules + cmds: + - go mod tidy + + clean: + desc: Clean build artifacts + cmds: + - rm -rf bin/ + - rm -f coverage.out coverage.html + + check: + desc: Run all checks (fmt, vet, lint, test) + cmds: + - task: fmt + - task: vet + - task: lint + - task: test diff --git a/cmd/smallflow/main.go b/cmd/smallflow/main.go new file mode 100644 index 0000000..facc4d1 --- /dev/null +++ b/cmd/smallflow/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Build, run, and observe workflows without the overhead!") +} diff --git a/compose.debug.yaml b/compose.debug.yaml new file mode 100644 index 0000000..e97b22b --- /dev/null +++ b/compose.debug.yaml @@ -0,0 +1,8 @@ +services: + smallflow: + image: smallflow + build: + context: . + dockerfile: ./Dockerfile + ports: + - 3000:3000 diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..e97b22b --- /dev/null +++ b/compose.yaml @@ -0,0 +1,8 @@ +services: + smallflow: + image: smallflow + build: + context: . + dockerfile: ./Dockerfile + ports: + - 3000:3000 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c9c1e0d --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/morebec/smallflow + +go 1.24.8 diff --git a/project.json b/project.json new file mode 100644 index 0000000..af579ef --- /dev/null +++ b/project.json @@ -0,0 +1,5 @@ + +{ + "projectCode": "smallflow", + "scope": "internal" +}