Skip to content

Commit da4714b

Browse files
author
Test
committed
feat: initial deployscope release
Lightweight Kubernetes deployment monitor with REST API. Extracted from internal Helm chart project as standalone service.
0 parents  commit da4714b

20 files changed

Lines changed: 2119 additions & 0 deletions

File tree

.dockerignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
bin/
2+
.git/
3+
.github/
4+
.claude/
5+
*.md
6+
!go.mod
7+
!go.sum
8+
Makefile
9+
deploy/
10+
coverage.out

.github/workflows/ci.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
security-events: write
12+
13+
jobs:
14+
test:
15+
name: Test
16+
runs-on: ubuntu-latest
17+
strategy:
18+
matrix:
19+
go-version: ['1.24', '1.25']
20+
steps:
21+
- uses: actions/checkout@v4
22+
- uses: actions/setup-go@v5
23+
with:
24+
go-version: ${{ matrix.go-version }}
25+
- run: make deps
26+
- run: make test
27+
28+
lint:
29+
name: Lint
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v4
33+
- uses: actions/setup-go@v5
34+
with:
35+
go-version: '1.25'
36+
- uses: golangci/golangci-lint-action@v7
37+
with:
38+
version: v2.8.0
39+
args: --timeout=5m
40+
- run: make fmt
41+
- run: git diff --exit-code
42+
43+
security:
44+
name: Security Scan
45+
runs-on: ubuntu-latest
46+
steps:
47+
- uses: actions/checkout@v4
48+
- name: Run Trivy vulnerability scanner
49+
uses: aquasecurity/trivy-action@master
50+
with:
51+
scan-type: fs
52+
scan-ref: .
53+
format: sarif
54+
output: trivy-results.sarif
55+
- name: Upload Trivy results to GitHub Security
56+
uses: github/codeql-action/upload-sarif@v4
57+
if: always()
58+
with:
59+
sarif_file: trivy-results.sarif

.github/workflows/release.yml

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
tag:
10+
description: 'Tag to release (e.g., v0.2.6)'
11+
required: true
12+
type: string
13+
14+
permissions:
15+
contents: write
16+
17+
jobs:
18+
test:
19+
name: Test before release
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
ref: ${{ github.event.inputs.tag || github.ref }}
25+
- uses: actions/setup-go@v5
26+
with:
27+
go-version: '1.25'
28+
- run: make test
29+
30+
release:
31+
name: Release
32+
needs: test
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: Resolve tag
36+
id: tag
37+
run: |
38+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
39+
echo "version=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
40+
else
41+
echo "version=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
42+
fi
43+
44+
- uses: actions/checkout@v4
45+
with:
46+
ref: ${{ steps.tag.outputs.version }}
47+
fetch-depth: 0
48+
- uses: actions/setup-go@v5
49+
with:
50+
go-version: '1.25'
51+
52+
- name: Get project name
53+
id: project
54+
run: echo "name=$(basename $GITHUB_REPOSITORY)" >> $GITHUB_OUTPUT
55+
56+
- name: Build and package binaries
57+
run: |
58+
VERSION=${{ steps.tag.outputs.version }}
59+
VERSION_NUM=${VERSION#v}
60+
PROJECT=${{ steps.project.outputs.name }}
61+
LDFLAGS="-s -w -X main.version=${VERSION_NUM}"
62+
63+
platforms=(
64+
"linux/amd64"
65+
"linux/arm64"
66+
"darwin/amd64"
67+
"darwin/arm64"
68+
"windows/amd64"
69+
)
70+
71+
mkdir -p dist staging
72+
73+
for platform in "${platforms[@]}"; do
74+
GOOS="${platform%/*}"
75+
GOARCH="${platform#*/}"
76+
binary="${PROJECT}"
77+
archive="${PROJECT}_${VERSION_NUM}_${GOOS}_${GOARCH}"
78+
79+
if [ "$GOOS" = "windows" ]; then
80+
binary="${binary}.exe"
81+
GOOS=$GOOS GOARCH=$GOARCH go build -ldflags="$LDFLAGS" -o "staging/${binary}" ./cmd/${PROJECT}/
82+
cd staging && zip "../dist/${archive}.zip" "${binary}" && cd ..
83+
else
84+
GOOS=$GOOS GOARCH=$GOARCH go build -ldflags="$LDFLAGS" -o "staging/${binary}" ./cmd/${PROJECT}/
85+
tar -czf "dist/${archive}.tar.gz" -C staging "${binary}"
86+
fi
87+
rm -f "staging/${binary}"
88+
done
89+
90+
- name: Generate checksums
91+
run: |
92+
cd dist
93+
sha256sum * > checksums.txt
94+
95+
- name: Extract release notes from CHANGELOG
96+
id: notes
97+
run: |
98+
TAG=${{ steps.tag.outputs.version }}
99+
VERSION=${TAG#v}
100+
PROJECT=${{ steps.project.outputs.name }}
101+
REPO=${{ github.repository }}
102+
103+
CHANGELOG=$(awk "/^## \[${VERSION}\]/{found=1; next} /^## \[/{found=0} found" CHANGELOG.md 2>/dev/null || true)
104+
if [ -z "$CHANGELOG" ]; then
105+
CHANGELOG="Release ${TAG}"
106+
fi
107+
108+
{
109+
echo "${CHANGELOG}"
110+
echo ""
111+
echo "## Install"
112+
echo ""
113+
echo '```bash'
114+
echo "# macOS (Apple Silicon)"
115+
echo "curl -LO https://github.com/${REPO}/releases/download/${TAG}/${PROJECT}_${VERSION}_darwin_arm64.tar.gz"
116+
echo "tar -xzf ${PROJECT}_${VERSION}_darwin_arm64.tar.gz"
117+
echo "sudo mv ${PROJECT} /usr/local/bin/"
118+
echo ""
119+
echo "# macOS (Intel)"
120+
echo "curl -LO https://github.com/${REPO}/releases/download/${TAG}/${PROJECT}_${VERSION}_darwin_amd64.tar.gz"
121+
echo "tar -xzf ${PROJECT}_${VERSION}_darwin_amd64.tar.gz"
122+
echo "sudo mv ${PROJECT} /usr/local/bin/"
123+
echo ""
124+
echo "# Linux (amd64)"
125+
echo "curl -LO https://github.com/${REPO}/releases/download/${TAG}/${PROJECT}_${VERSION}_linux_amd64.tar.gz"
126+
echo "tar -xzf ${PROJECT}_${VERSION}_linux_amd64.tar.gz"
127+
echo "sudo mv ${PROJECT} /usr/local/bin/"
128+
echo '```'
129+
echo ""
130+
echo "**Verify checksums:** \`sha256sum -c checksums.txt\`"
131+
} > /tmp/release-body.md
132+
133+
echo "notes<<EOF" >> $GITHUB_OUTPUT
134+
cat /tmp/release-body.md >> $GITHUB_OUTPUT
135+
echo "EOF" >> $GITHUB_OUTPUT
136+
137+
- uses: softprops/action-gh-release@v2
138+
with:
139+
tag_name: ${{ steps.tag.outputs.version }}
140+
body: ${{ steps.notes.outputs.notes }}
141+
files: dist/*
142+
generate_release_notes: false

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
# Claude Code
3+
.claude/
4+
CLAUDE.local.md

CLAUDE.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Project: deployscope
2+
3+
## Commands
4+
- `make build` — Build binary
5+
- `make test` — Run tests with race detection
6+
- `make lint` — Run golangci-lint
7+
- `make fmt` — Format with gofmt/goimports
8+
- `make clean` — Clean build artifacts
9+
10+
## Architecture
11+
- Entry: cmd/deployscope/main.go (minimal, delegates to internal/)
12+
- internal/k8s/ — Kubernetes client, cache, deployment fetching
13+
- internal/server/ — HTTP handlers, routes, HTML, OpenAPI spec
14+
15+
## Conventions
16+
- Minimal main.go — create client, create server, ListenAndServe
17+
- Internal packages: short single-word names (k8s, server)
18+
- Struct-based domain models with json tags
19+
- Standard Go formatting (gofmt/goimports)
20+
- Version injected via LDFLAGS at build time
21+
22+
## Anti-Patterns
23+
- NEVER use raw SQL without parameterization
24+
- NEVER skip error handling — always check returned errors
25+
- NEVER use init() functions unless absolutely necessary
26+
- NEVER use global mutable state
27+
28+
## Verification
29+
- Run `make test` after code changes (includes -race)
30+
- Run `make lint` before marking complete
31+
- Run `go vet ./...` for suspicious constructs

Dockerfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM golang:1.23-alpine AS builder
2+
3+
WORKDIR /app
4+
5+
COPY go.mod go.sum ./
6+
RUN go mod download
7+
8+
COPY cmd/ ./cmd/
9+
COPY internal/ ./internal/
10+
11+
ARG VERSION=dev
12+
RUN CGO_ENABLED=0 GOOS=linux go build \
13+
-ldflags "-s -w -X main.version=${VERSION}" \
14+
-o deployscope ./cmd/deployscope
15+
16+
FROM alpine:3.19
17+
18+
RUN apk --no-cache add ca-certificates
19+
COPY --from=builder /app/deployscope /usr/local/bin/deployscope
20+
21+
EXPOSE 8080
22+
23+
USER 1001:1001
24+
25+
ENTRYPOINT ["deployscope"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 ppiankov
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
BINARY := deployscope
2+
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null | sed 's/^v//' || echo "dev")
3+
LDFLAGS := -ldflags "-s -w -X main.version=$(VERSION)"
4+
5+
.PHONY: all build test lint fmt clean deps docker-build help
6+
7+
all: deps fmt lint test build
8+
9+
build: ## Build binary
10+
CGO_ENABLED=0 go build $(LDFLAGS) -o bin/$(BINARY) ./cmd/deployscope
11+
12+
test: ## Run tests with race detection
13+
go test -race -cover ./...
14+
15+
lint: ## Run golangci-lint
16+
golangci-lint run ./...
17+
18+
fmt: ## Format code
19+
gofmt -w .
20+
goimports -w .
21+
22+
deps: ## Download dependencies
23+
go mod download
24+
25+
docker-build: ## Build Docker image
26+
docker build -t $(BINARY):$(VERSION) .
27+
28+
clean: ## Clean build artifacts
29+
rm -rf bin/ coverage.out
30+
31+
help: ## Show this help
32+
@grep -E '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'

0 commit comments

Comments
 (0)