Skip to content

Epic: Phase 1 - Foundation & Infrastructure #1

@rianjs

Description

@rianjs

Phase 1: Foundation & Infrastructure

Priority: P0 - Must be completed first, blocks all other work
Estimated Sub-tasks: 4

Summary

Establish the foundational infrastructure needed for all subsequent development. This includes CI/CD pipeline, linting, build system improvements, and version injection.


Sub-Tasks

1. Add CI Workflow for Pull Requests

  • Create .github/workflows/ci.yml
  • Trigger on push to main and PRs to main
  • Steps: checkout, setup Go 1.22, download deps, build, test (with race detection)
  • Add lint job using golangci-lint-action

Implementation:

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.22'
      - run: go mod download
      - run: go build -v ./...
      - run: go test -v -race -coverprofile=coverage.out ./...

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.22'
      - uses: golangci/golangci-lint-action@v7
        with:
          version: v2.8.0

2. Add golangci-lint Configuration

  • Create .golangci.yml
  • Enable standard linters: errcheck, govet, ineffassign, staticcheck, unused, misspell
  • Configure goimports with local prefixes for github.com/piekstra/slack-cli
  • Fix any existing lint errors

Implementation:

version: "2"

linters:
  enable:
    - errcheck
    - govet
    - ineffassign
    - staticcheck
    - unused
    - misspell
  exclusions:
    rules:
      - path: _test\.go
        linters:
          - errcheck

formatters:
  enable:
    - gofmt
    - goimports
  settings:
    goimports:
      local-prefixes:
        - github.com/piekstra/slack-cli

run:
  timeout: 5m

3. Update Makefile with Standard Targets

  • Add VERSION, COMMIT, DATE variables from git
  • Add LDFLAGS for version injection
  • Update build target to use ldflags
  • Add test-cover target for coverage reports
  • Add test-short target for quick tests
  • Add lint target
  • Add fmt target
  • Add deps target
  • Add verify target

Implementation:

BINARY := slack-cli
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
DATE := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
LDFLAGS := -ldflags "-s -w \
    -X github.com/piekstra/slack-cli/internal/version.Version=$(VERSION) \
    -X github.com/piekstra/slack-cli/internal/version.Commit=$(COMMIT) \
    -X github.com/piekstra/slack-cli/internal/version.Date=$(DATE)"

build:
    go build $(LDFLAGS) -o bin/$(BINARY) .

test:
    go test -v -race ./...

test-cover:
    go test -v -race -coverprofile=coverage.out ./...
    go tool cover -html=coverage.out -o coverage.html

test-short:
    go test -v -short ./...

lint:
    golangci-lint run

fmt:
    go fmt ./...
    goimports -w .

deps:
    go mod download
    go mod tidy

verify:
    go mod verify

clean:
    rm -rf bin/ dist/ coverage.out coverage.html

4. Add Version Package with Build-Time Info

  • Create internal/version/version.go
  • Define Version, Commit, Date variables with defaults
  • Update root command to use version package
  • Update version template to show commit and build date

Implementation:

// internal/version/version.go
package version

var (
    Version = "dev"
    Commit  = "unknown"
    Date    = "unknown"
)

Update root command:

import "github.com/piekstra/slack-cli/internal/version"

cmd.Version = version.Version
cmd.SetVersionTemplate("slack-cli version {{.Version}} (commit: " + version.Commit + ", built: " + version.Date + ")\n")

Acceptance Criteria

  • make build produces binary at bin/slack-cli
  • ./bin/slack-cli --version shows version, commit, and date
  • make test runs all tests with race detection
  • make lint runs without errors
  • CI workflow passes on new PRs
  • PR to main requires passing CI

Dependencies

  • Blocks: Phase 2 (Testing), Phase 3 (Restructuring), all subsequent phases

Files to Create/Modify

Create:

  • .github/workflows/ci.yml
  • .golangci.yml
  • internal/version/version.go

Modify:

  • Makefile
  • cmd/root.go

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions