Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3d80ba4
Add Docker support for figurine
yacosta738 Apr 30, 2025
d6dc38c
chore(Makefile): 🛠️ simplify and clean up Makefile commands
yacosta738 Apr 30, 2025
b5ff94f
Update Dockerfile
yacosta738 Apr 30, 2025
81852a6
Merge pull request #1 from yacosta738/add-docker
yacosta738 Apr 30, 2025
94e104f
feat(docker): ✨ update Dockerfile for multi-platform builds and impro…
yacosta738 Apr 30, 2025
815f333
Merge pull request #2 from yacosta738/feature/release-app
yacosta738 Apr 30, 2025
c8d7102
chore(Makefile): 🛠️ simplify clean command in Makefile
yacosta738 Apr 30, 2025
5b95797
chore(Dockerfile): 🛠️ update Go version to 1.22-alpine
yacosta738 Apr 30, 2025
1284602
feat(install): ✨ add figurine installer script with dynamic repo dete…
yacosta738 Apr 30, 2025
36cce53
feat(install): ✨ improve binary extraction logic in installer script
yacosta738 Apr 30, 2025
8053f13
feat(install): ✨ enhance release info fetching with error handling an…
yacosta738 Apr 30, 2025
6cac1d4
fix(install): 🐛 add checksum validation for downloaded binaries
yacosta738 Apr 30, 2025
e5e281d
refactor(install): 🔧 reorganize banner printing function and enable s…
yacosta738 Apr 30, 2025
a1b9c8d
feat(install): ✨ add support for custom GitHub repository specification
yacosta738 Apr 30, 2025
7e8d57a
Merge pull request #3 from yacosta738/feature/install
yacosta738 Apr 30, 2025
5f53ede
fix(install): 🐛 improve checksum verification process
yacosta738 Apr 30, 2025
c9d73db
Merge pull request #4 from yacosta738/fix/checksum
yacosta738 Apr 30, 2025
99ff8a0
fix(install): 🐛 update default GitHub repository owner to yacosta738
yacosta738 Apr 30, 2025
f9a568d
Merge branch 'master' of github.com:yacosta738/figurine
yacosta738 Apr 30, 2025
ca8db6c
fix(install): 🐛 update default repository example in help message
yacosta738 Apr 30, 2025
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
5 changes: 5 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"tasks": {
"build": "go build"
}
}
86 changes: 86 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: write
packages: write

jobs:
build:
name: Build and Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
cache: true

- name: Build binaries
run: make build-all

- name: Create checksums
run: cd dist && sha256sum *.tar.gz > checksums.txt

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
dist/*.tar.gz
dist/checksums.txt
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
generate_release_notes: true

docker:
name: Build and Push Docker Image
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ secrets.DOCKER_USERNAME }}/figurine
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable=${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, 'rc') }}

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ github.ref_name }}
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Build stage
FROM golang:1.22-alpine AS build

WORKDIR /app

# Install dependencies
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

# Build the binary with proper flags
ARG VERSION=dev
RUN CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=${VERSION}" -o figurine .

# Final stage - minimal image
FROM alpine:latest

# Add CA certificates for any HTTPS requests
RUN apk --no-cache add ca-certificates

# Create non-root user for security
RUN adduser -D -u 10001 appuser
WORKDIR /home/appuser

# Copy only the binary from the build stage
COPY --from=build /app/figurine .
RUN chmod +x ./figurine

# Use non-root user
USER appuser

ENTRYPOINT ["./figurine"]
140 changes: 53 additions & 87 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,99 +1,65 @@
help: ## Show help messages.
@grep -E '^[0-9a-zA-Z_-]+:(.*?## .*)?$$' $(MAKEFILE_LIST) | sed 's/^Makefile://' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
# Makefile for Figurine

run="."
dir="./..."
short="-short"
flags=""
timeout=40s
build_tag=$(shell git describe --abbrev=0 --tags)
current_sha=$(shell git rev-parse --short HEAD)
# Variables
BINARY_NAME=figurine
VERSION=$(shell git describe --tags --always --dirty)
LDFLAGS=-ldflags "-s -w -X main.version=$(VERSION)"
GO_FILES=$(shell find . -name "*.go" -type f)
DOCKER_IMAGE=figurine
DOCKER_CONTAINER=figurine-container
PLATFORMS=linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64
OUTPUT_DIR=dist

TARGET=$(shell git describe --abbrev=0 --tags)
RELEADE_NAME=figurine
DEPLOY_FOLDER=deploy
CHECKSUM_FILE=CHECKSUM
MAKEFLAGS += -j1
LINUX_ARCH = amd64 arm arm64
# Go commands
build:
go build $(LDFLAGS) -o $(BINARY_NAME) .

.PHONY: install
install: ## Install the binary.
@go install -trimpath -ldflags="-s -w -X main.version=$(build_tag) -X main.currentSha=$(current_sha)"
install:
go install $(LDFLAGS) .

.PHONY: unittest
unittest: ## Run unit tests in watch mode. You can set: [run, timeout, short, dir, flags]. Example: make unittest flags="-race".
@echo "running tests on $(run). waiting for changes..."
@-zsh -c "go test -trimpath --timeout=$(timeout) $(short) $(dir) -run $(run) $(flags); repeat 100 printf '#'; echo"
@reflex -d none -r "(\.go$$)|(go.mod)" -- zsh -c "go test -trimpath --timeout=$(timeout) $(short) $(dir) -run $(run) $(flags); repeat 100 printf '#'"
test:
go test -v ./...

.PHONY: lint
lint: ## Run linters.
go fmt ./...
go vet ./...
golangci-lint run ./...
clean:
go clean
[ -f $(BINARY_NAME) ] && rm -f $(BINARY_NAME) || true
rm -rf $(OUTPUT_DIR)

.PHONY: dependencies
dependencies: ## Install dependencies requried for development operations.
@go install github.com/cespare/reflex@latest
@go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
@go install github.com/psampaz/go-mod-outdated@latest
@go install github.com/jondot/goweight@latest
@go get -t -u golang.org/x/tools/cmd/cover
@go get -t -u github.com/sonatype-nexus-community/nancy@latest
@go get -u ./...
@go mod tidy
# Multi-platform builds
build-all: clean
mkdir -p $(OUTPUT_DIR)
$(foreach platform,$(PLATFORMS),\
$(eval OS := $(word 1,$(subst /, ,$(platform)))) \
$(eval ARCH := $(word 2,$(subst /, ,$(platform)))) \
$(eval EXTENSION := $(if $(filter windows,$(OS)),.exe,)) \
echo "Building $(OS)/$(ARCH)..." && \
GOOS=$(OS) GOARCH=$(ARCH) CGO_ENABLED=0 \
go build $(LDFLAGS) -o $(OUTPUT_DIR)/$(BINARY_NAME)_$(OS)_$(ARCH)$(EXTENSION) . && \
cd $(OUTPUT_DIR) && \
tar -czvf $(BINARY_NAME)_$(OS)_$(ARCH).tar.gz $(BINARY_NAME)_$(OS)_$(ARCH)$(EXTENSION) && \
cd - ;\
)

.PHONY: clean
clean: ## Clean test caches and tidy up modules.
@go clean -testcache
@go mod tidy
@rm -rf $(DEPLOY_FOLDER)
release: build-all
cd $(OUTPUT_DIR) && sha256sum *.tar.gz > checksums.txt

.PHONY: tmpfolder
tmpfolder: ## Create the temporary folder.
@mkdir -p $(DEPLOY_FOLDER)
@rm -rf $(DEPLOY_FOLDER)/$(CHECKSUM_FILE) 2> /dev/null
# Docker commands
docker-build:
docker build -t $(DOCKER_IMAGE) .

.PHONY: linux
linux: tmpfolder
linux: $(LINUX_ARCH)
$(LINUX_ARCH): ## Build for GNU/Linux.
@GOOS=linux GOARCH=$@ CGO_ENABLED=0 go build -trimpath -ldflags="-s -w -X main.version=$(build_tag) -X main.currentSha=$(current_sha)" -o $(DEPLOY_FOLDER)/$(RELEADE_NAME) .
@tar -czf $(DEPLOY_FOLDER)/figurine_linux_$@_$(TARGET).tar.gz $(DEPLOY_FOLDER)/$(RELEADE_NAME)
@cd $(DEPLOY_FOLDER) ; sha256sum figurine_linux_$@_$(TARGET).tar.gz >> $(CHECKSUM_FILE)
@echo "Linux target:" $(DEPLOY_FOLDER)/figurine_linux_$@_$(TARGET).tar.gz
@rm $(DEPLOY_FOLDER)/$(RELEADE_NAME)
docker-run:
docker run --rm --name $(DOCKER_CONTAINER) $(DOCKER_IMAGE)

.PHONY: darwin
darwin: tmpfolder
darwin: ## Build for Mac.
@GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w -X main.version=$(build_tag) -X main.currentSha=$(current_sha)" -o $(DEPLOY_FOLDER)/$(RELEADE_NAME) .
@tar -czf $(DEPLOY_FOLDER)/figurine_darwin_amd64_$(TARGET).tar.gz $(DEPLOY_FOLDER)/$(RELEADE_NAME)
@cd $(DEPLOY_FOLDER) ; sha256sum figurine_darwin_amd64_$(TARGET).tar.gz >> $(CHECKSUM_FILE)
@echo "Darwin target:" $(DEPLOY_FOLDER)/figurine_darwin_amd64_$(TARGET).tar.gz
@rm $(DEPLOY_FOLDER)/$(RELEADE_NAME)
docker-clean:
docker rm -f $(DOCKER_CONTAINER) 2>/dev/null || true
docker rmi -f $(DOCKER_IMAGE) 2>/dev/null || true

.PHONY: windows
windows: tmpfolder
windows: ## Build for windoze.
@GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w -X main.version=$(build_tag) -X main.currentSha=$(current_sha)" -o $(DEPLOY_FOLDER)/$(RELEADE_NAME).exe .
@zip -r $(DEPLOY_FOLDER)/figurine_windows_amd64_$(TARGET).zip $(DEPLOY_FOLDER)/$(RELEADE_NAME).exe
@cd $(DEPLOY_FOLDER) ; sha256sum figurine_windows_amd64_$(TARGET).zip >> $(CHECKSUM_FILE)
@echo "Windows target:" $(DEPLOY_FOLDER)/figurine_windows_amd64_$(TARGET).zip
@rm $(DEPLOY_FOLDER)/$(RELEADE_NAME).exe
# Docker multi-platform build
docker-buildx:
docker buildx create --use --name multiplatform-builder || true
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 \
--tag $(DOCKER_IMAGE):$(VERSION) \
--tag $(DOCKER_IMAGE):latest \
--push .

.PHONY: release
release: ## Create releases for Linux, Mac, and windoze.
release: linux darwin windows

.PHONY: coverage
coverage: ## Show the test coverage on browser.
go test -covermode=count -coverprofile=coverage.out ./...
go tool cover -func=coverage.out | tail -n 1
go tool cover -html=coverage.out

.PHONY: audit
audit: ## Audit the code for updates, vulnerabilities and binary weight.
go list -u -m -json all | go-mod-outdated -update -direct
go list -json -deps | nancy sleuth
goweight | head -n 20
.PHONY: build install test clean build-all release docker-build docker-run docker-clean docker-buildx
84 changes: 82 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ Print your name in style

1. [Installation](#installation)
2. [Usage](#usage)
3. [See Also](#see-also)
4. [License](#license)
3. [Docker](#docker)
4. [Building from Source](#building-from-source)
5. [Creating Releases](#creating-releases)
6. [See Also](#see-also)
7. [License](#license)

## Installation

Expand Down Expand Up @@ -59,6 +62,83 @@ This application is very light weight, so feel free to add it to your
.zshrc/.bashrc file, so each time you open a new shell it shows you a nice
message.

## Docker

To build the Docker image:

```bash
make docker-build
```

To run the Docker container:

```bash
make docker-run
```

To build multi-platform Docker images (requires Docker Buildx):

```bash
make docker-buildx
```

To clean up the Docker image and container:

```bash
make docker-clean
```

## Building from Source

### Local Development Build

To build the project for your local machine:

```bash
make build
```

### Cross-Platform Builds

To build for multiple platforms (Linux, macOS, Windows):

```bash
make build-all
```

This creates binaries in the `dist` folder for the following platforms:
- Linux (amd64, arm64)
- macOS (amd64, arm64)
- Windows (amd64)

Each binary is compressed into a tar.gz archive with platform-specific naming.

## Creating Releases

### Manual Release

1. Build all platform binaries:
```bash
make release
```

2. This will create compressed archives and a checksums.txt file in the `dist` folder.

### Automated Release

Releases are automated using GitHub Actions. To create a new release:

1. Tag the commit with a version number:
```bash
git tag v1.0.0
git push origin v1.0.0
```

2. GitHub Actions will automatically:
- Build binaries for all supported platforms
- Create a new GitHub Release with the binaries
- Build and push Docker images to Docker Hub (if configured)

## See Also

See also [Rainbow][rainbow], which is the library that colours the output.
Expand Down
Loading