diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 09c96e1..461de99 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -30,6 +30,7 @@ jobs: - bat - just - opencode + - ccc baseImage: - debian:latest - ubuntu:latest diff --git a/README.md b/README.md index 0ed7c66..6e61db4 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ This repository contains a _collection_ of Features. | Ruff | https://docs.astral.sh/ruff/ | An extremely fast Python linter and code formatter, written in Rust. | | OpenCode | https://opencode.ai/ | AI coding agent, built for the terminal. An open-source alternative to Claude Code with support for multiple LLM providers. | | Codex-cli | https://github.com/openai/codex | Codex CLI is an experimental project under active development. | +| ccc | https://github.com/jsburckhardt/co-config | A TUI tool to interactively configure and view GitHub Copilot CLI settings. | @@ -337,3 +338,20 @@ Running `just` inside the built container will print the help menu of just. ```bash just --version ``` + +### `ccc` + +Running `ccc` inside the built container will print the version of ccc (Copilot Config CLI). + +```jsonc +{ + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "ghcr.io/jsburckhardt/devcontainer-features/ccc:1": {} + } +} +``` + +```bash +ccc --version +``` diff --git a/src/ccc/devcontainer-feature.json b/src/ccc/devcontainer-feature.json new file mode 100644 index 0000000..36ecbbd --- /dev/null +++ b/src/ccc/devcontainer-feature.json @@ -0,0 +1,13 @@ +{ + "name": "ccc", + "id": "ccc", + "version": "1.0.0", + "description": "A TUI tool to interactively configure and view GitHub Copilot CLI settings.", + "options": { + "version": { + "type": "string", + "default": "latest", + "description": "Version of ccc to install from GitHub releases e.g. v0.1.5" + } + } +} diff --git a/src/ccc/install.sh b/src/ccc/install.sh new file mode 100644 index 0000000..53f6184 --- /dev/null +++ b/src/ccc/install.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +# Variables +REPO_OWNER="jsburckhardt" +REPO_NAME="co-config" +BINARY_NAME="ccc" +CCC_VERSION="${VERSION:-"latest"}" +GITHUB_API_REPO_URL="https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases" + +set -e + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi + apt-get -y install --no-install-recommends "$@" + fi +} + +# Make sure we have curl and jq +check_packages curl jq ca-certificates tar + +# Function to get the latest version from GitHub API +get_latest_version() { + curl -s "${GITHUB_API_REPO_URL}/latest" | jq -r ".tag_name" +} + +# Check if a version is passed as an argument +if [ -z "$CCC_VERSION" ] || [ "$CCC_VERSION" == "latest" ]; then + # No version provided, get the latest version + CCC_VERSION=$(get_latest_version) + echo "No version provided or 'latest' specified, installing the latest version: $CCC_VERSION" +else + echo "Installing version from environment variable: $CCC_VERSION" +fi + +# Determine the OS and architecture +OS=$(uname -s | tr '[:upper:]' '[:lower:]') +ARCH=$(uname -m) + +case "$ARCH" in + x86_64) + ARCH="amd64" + ;; + aarch64) + ARCH="arm64" + ;; + *) + echo "Unsupported architecture: $ARCH" + exit 1 + ;; +esac + +case "$OS" in + linux) + OS="linux" + ;; + darwin) + OS="darwin" + ;; + *) + echo "Unsupported OS: $OS" + exit 1 + ;; +esac + +# Construct the download URL +# Asset pattern: co-config_{os}_{arch}.tar.gz +DOWNLOAD_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/${CCC_VERSION}/${REPO_NAME}_${OS}_${ARCH}.tar.gz" + +# Create a temporary directory for the download +TMP_DIR=$(mktemp -d) +cd "$TMP_DIR" || exit + +echo "Downloading $BINARY_NAME from $DOWNLOAD_URL" +curl -sSL "$DOWNLOAD_URL" -o "${BINARY_NAME}.tar.gz" + +# Extract the tarball +echo "Extracting $BINARY_NAME..." +tar -xzf "${BINARY_NAME}.tar.gz" + +# Move the binary to /usr/local/bin +echo "Installing $BINARY_NAME..." +mv "$BINARY_NAME" /usr/local/bin/ +chmod +x /usr/local/bin/$BINARY_NAME + +# Cleanup +cd - || exit +rm -rf "$TMP_DIR" + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Verify installation +echo "Verifying installation..." +$BINARY_NAME --version + +echo "Done!" diff --git a/test/_global/all-tools.sh b/test/_global/all-tools.sh index 98cc7cd..aef7f35 100755 --- a/test/_global/all-tools.sh +++ b/test/_global/all-tools.sh @@ -18,5 +18,6 @@ check "zarf" zarf version check "codex" codex --version check "just" just --version check "opencode" opencode --version +check "ccc" ccc --version reportResults diff --git a/test/_global/ccc-specific-version.sh b/test/_global/ccc-specific-version.sh new file mode 100644 index 0000000..e2206cd --- /dev/null +++ b/test/_global/ccc-specific-version.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e +source dev-container-features-test-lib +check "ccc with specific version" /bin/bash -c "ccc --version | grep '0.1.5'" + +reportResults diff --git a/test/_global/scenarios.json b/test/_global/scenarios.json index a4b85c3..58a9945 100644 --- a/test/_global/scenarios.json +++ b/test/_global/scenarios.json @@ -19,7 +19,8 @@ "zarf": {}, "codex": {}, "just": {}, - "opencode": {} + "opencode": {}, + "ccc": {} } }, "flux-specific-version": { @@ -147,5 +148,13 @@ "version": "1.0.107" } } + }, + "ccc-specific-version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "ccc": { + "version": "v0.1.5" + } + } } } diff --git a/test/ccc/test.sh b/test/ccc/test.sh new file mode 100644 index 0000000..fd692de --- /dev/null +++ b/test/ccc/test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +source dev-container-features-test-lib +check "ccc" ccc --version +reportResults