Skip to content
Closed
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
126 changes: 126 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Release

on:
push:
tags:
- 'v*'

permissions:
contents: write
packages: write
issues: write

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

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
if: env.DOCKER_USERNAME != ''

- name: Log in to Docker Hub
uses: docker/login-action@v3
if: env.DOCKER_USERNAME != ''
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Run tests
run: |
go test -v ./...
./scripts/ci.sh

- name: Generate completions
run: |
go build -o cu ./cmd/cu
./cu completion bash > completions/cu.bash
./cu completion zsh > completions/_cu
./cu completion fish > completions/cu.fish

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
GPG_FINGERPRINT: ${{ secrets.GPG_FINGERPRINT }}

- name: Create Release Issue
uses: actions/github-script@v7
if: success()
with:
script: |
const tag = context.ref.replace('refs/tags/', '');
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Release ${tag} - Post-Release Tasks`,
body: `## Release ${tag} has been published! 馃帀

### Automated Tasks Completed:
- [x] Built binaries for all platforms
- [x] Created GitHub release with artifacts
- [x] Generated checksums
- [x] Updated Homebrew tap (if token provided)
- [x] Published Docker images (if credentials provided)

### Manual Tasks Required:
- [ ] Verify Homebrew installation: \`brew install timimsms/clickup/clickup-cli\`
- [ ] Test Docker image: \`docker run clickup/cli:${tag} --version\`
- [ ] Update documentation if needed
- [ ] Announce release on social media
- [ ] Close this issue when all tasks are complete

### Release Notes:
https://github.com/${context.repo.owner}/${context.repo.repo}/releases/tag/${tag}`,
labels: ['release', 'documentation']
});
console.log(`Created issue #${issue.data.number}`);

test-install:
needs: release
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Test direct download
shell: bash
run: |
# Determine OS and architecture
OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
ARCH="x86_64"
if [ "$OS" = "macos" ]; then OS="darwin"; fi
if [ "$OS" = "windows" ]; then
OS="windows"
EXT=".zip"
else
EXT=".tar.gz"
fi

# Download and extract
TAG="${{ github.ref_name }}"
URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/cu_${OS}_${ARCH}${EXT}"
echo "Downloading from: $URL"

if [ "$OS" = "windows" ]; then
curl -L -o cu.zip "$URL"
unzip cu.zip
./cu.exe --version
else
curl -L "$URL" | tar xz
./cu --version
fi
159 changes: 159 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# GoReleaser configuration for ClickUp CLI
# Documentation: https://goreleaser.com
version: 2

project_name: cu

before:
hooks:
- go mod tidy
- go generate ./...

builds:
- id: cu
main: ./cmd/cu
binary: cu
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
- "386"
goarm:
- "7"
# Skip unsupported combinations
ignore:
- goos: darwin
goarch: "386"
- goos: windows
goarch: arm64
# Build flags for smaller binaries
ldflags:
- -s -w
- -X github.com/tim/cu/internal/version.Version={{.Version}}
- -X github.com/tim/cu/internal/version.Commit={{.Commit}}
- -X github.com/tim/cu/internal/version.BuildDate={{.Date}}
- -X github.com/tim/cu/internal/version.BuiltBy=goreleaser

archives:
- id: cu-archive
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
builds:
- cu
format: tar.gz
format_overrides:
- goos: windows
format: zip
files:
- README.md
- LICENSE
- CHANGELOG.md
- src: completions/*
dst: completions

checksum:
name_template: 'checksums.txt'
algorithm: sha256

signs:
- artifacts: checksum
cmd: gpg
args:
- "--batch"
- "--local-user"
- "{{ .Env.GPG_FINGERPRINT }}"
- "--output"
- "${signature}"
- "--detach-sign"
- "${artifact}"

sboms:
- artifacts: archive
documents:
- "{{ .ArtifactName }}.sbom.json"

snapshot:
version_template: "{{ incpatch .Version }}-dev"

changelog:
sort: asc
use: github
filters:
exclude:
- '^docs:'
- '^test:'
- '^chore:'
- '^ci:'
groups:
- title: 'New Features'
regexp: '^feat'
- title: 'Bug Fixes'
regexp: '^fix'
- title: 'Performance Improvements'
regexp: '^perf'
- title: 'Breaking Changes'
regexp: '^breaking'

release:
github:
owner: timimsms
name: cu
draft: false
prerelease: auto
name_template: "{{.ProjectName}} v{{.Version}}"
header: |
## ClickUp CLI v{{.Version}}

**Full Changelog**: https://github.com/timimsms/cu/compare/{{ .PreviousTag }}...{{ .Tag }}
footer: |
## Installation

### Homebrew (macOS/Linux)
```bash
brew install timimsms/clickup/clickup-cli
```

### npm
```bash
npm install -g @clickup/cli
```

### Docker
```bash
docker run -it clickup/cli:{{ .Version }}
```

### Direct Download
See the assets below for platform-specific binaries.

# Homebrew tap configuration (will create PR to separate tap repo)
# Requires HOMEBREW_TAP_GITHUB_TOKEN secret
# brews section is deprecated in v2, using separate action in workflow instead

# Docker configuration
dockers:
- image_templates:
- "clickup/cli:{{ .Tag }}"
- "clickup/cli:v{{ .Major }}"
- "clickup/cli:v{{ .Major }}.{{ .Minor }}"
- "clickup/cli:latest"
dockerfile: Dockerfile.release
build_flag_templates:
- "--pull"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.title={{.ProjectName}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
- "--platform=linux/amd64,linux/arm64"
extra_files:
- completions/
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Changelog

All notable changes to the ClickUp CLI will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- Initial release of ClickUp CLI
- Core task management commands (list, create, view, update, close, reopen, delete)
- Bulk operations for efficient task management
- Export functionality with CSV, JSON, and Markdown formats
- Interactive mode with fuzzy search
- Secure authentication using OS keychain
- Multi-format output support (table, JSON, YAML, CSV)
- Comprehensive caching layer for performance
- Shell completion for bash, zsh, and fish

### Changed
- Nothing yet

### Deprecated
- Nothing yet

### Removed
- Nothing yet

### Fixed
- Nothing yet

### Security
- Implemented secure token storage using OS-specific keychains
- Added file path sanitization to prevent directory traversal attacks
30 changes: 30 additions & 0 deletions Dockerfile.release
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Dockerfile for ClickUp CLI releases
# This is used by GoReleaser for Docker image builds

FROM alpine:3.19

# Install ca-certificates for HTTPS requests
RUN apk --no-cache add ca-certificates

# Create non-root user
RUN addgroup -g 1000 -S cu && \
adduser -u 1000 -S cu -G cu

# Copy binary from GoReleaser
COPY cu /usr/local/bin/cu

# Copy shell completions
COPY completions /usr/share/cu/completions

# Set up working directory
WORKDIR /workspace

# Switch to non-root user
USER cu

# Verify installation
RUN cu --version

# Set entrypoint
ENTRYPOINT ["cu"]
CMD ["--help"]
Loading