Skip to content

Commit 6d8b018

Browse files
Ona Agentona-agent
andcommitted
Add release workflow and migrate devcontainer feature
- Add GitHub Actions workflow for building and releasing binaries - Migrate devcontainer feature from actions repository - Update feature configuration to v1.1.0 and new registry path - Add devcontainer feature publishing workflow Co-authored-by: Ona <no-reply@ona.com>
1 parent 51b3ae9 commit 6d8b018

7 files changed

Lines changed: 534 additions & 0 deletions

File tree

.devcontainer-feature/README.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Linear CLI (linctl) DevContainer Feature
2+
3+
This DevContainer Feature installs [linctl](https://github.com/nicholls-inc/linctl), a command-line interface for Linear project management.
4+
5+
## Usage
6+
7+
Add this feature to your `devcontainer.json`:
8+
9+
```json
10+
{
11+
"features": {
12+
"ghcr.io/nicholls-inc/linctl/linctl:1": {}
13+
}
14+
}
15+
```
16+
17+
## Options
18+
19+
| Option | Type | Default | Description |
20+
|--------|------|---------|-------------|
21+
| `version` | string | `latest` | Version of linctl to install. Use 'latest' for the most recent release or specify a version tag (e.g., 'v1.0.0') |
22+
| `installMethod` | string | `release` | Installation method: 'release' downloads pre-built binaries, 'source' builds from source code |
23+
24+
## Examples
25+
26+
### Install Latest Version (Default)
27+
28+
```json
29+
{
30+
"features": {
31+
"ghcr.io/nicholls-inc/linctl/linctl:1": {}
32+
}
33+
}
34+
```
35+
36+
### Install Specific Version
37+
38+
```json
39+
{
40+
"features": {
41+
"ghcr.io/nicholls-inc/linctl/linctl:1": {
42+
"version": "v1.0.0"
43+
}
44+
}
45+
}
46+
```
47+
48+
### Build from Source
49+
50+
```json
51+
{
52+
"features": {
53+
"ghcr.io/nicholls-inc/linctl/linctl:1": {
54+
"installMethod": "source"
55+
}
56+
}
57+
}
58+
```
59+
60+
## Installation Methods
61+
62+
### Release (Default)
63+
- Downloads pre-built binaries from GitHub releases
64+
- Faster installation
65+
- Includes checksum verification for security
66+
- Supports linux/amd64 and linux/arm64 architectures
67+
- Falls back to source build if release is unavailable
68+
69+
### Source
70+
- Builds linctl from source code
71+
- Requires Go compiler (automatically installed if missing)
72+
- Always uses the latest code from the repository
73+
- Useful for development or when pre-built binaries are unavailable
74+
75+
## Authentication
76+
77+
After installation, you'll need to authenticate with Linear:
78+
79+
```bash
80+
# OAuth authentication (recommended)
81+
linctl auth login --oauth
82+
83+
# API key authentication
84+
linctl auth login --api-key YOUR_API_KEY
85+
```
86+
87+
## Supported Architectures
88+
89+
- linux/amd64
90+
- linux/arm64
91+
92+
## Requirements
93+
94+
- Linux-based container
95+
- Internet access for downloading binaries or source code
96+
- For source builds: Go 1.23+ (automatically installed if missing)
97+
98+
## Verification
99+
100+
After installation, verify linctl is working:
101+
102+
```bash
103+
linctl --version
104+
linctl --help
105+
```
106+
107+
## Related
108+
109+
- [linctl GitHub Repository](https://github.com/nicholls-inc/linctl)
110+
- [Linear API Documentation](https://developers.linear.app/)
111+
- [DevContainer Features Specification](https://containers.dev/implementors/features/)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"id": "linctl",
3+
"version": "1.1.0",
4+
"name": "Linear CLI (linctl)",
5+
"description": "Installs linctl, a command-line interface for Linear project management",
6+
"documentationURL": "https://github.com/nicholls-inc/linctl",
7+
"licenseURL": "https://github.com/nicholls-inc/linctl/blob/master/LICENSE",
8+
"keywords": [
9+
"linear",
10+
"cli",
11+
"project-management",
12+
"linctl"
13+
],
14+
"options": {
15+
"version": {
16+
"type": "string",
17+
"description": "Version of linctl to install. Use 'latest' for the most recent release.",
18+
"default": "latest"
19+
},
20+
"installMethod": {
21+
"type": "string",
22+
"enum": [
23+
"release",
24+
"source"
25+
],
26+
"default": "release",
27+
"description": "Installation method: 'release' downloads pre-built binaries, 'source' builds from source code"
28+
}
29+
},
30+
"containerEnv": {
31+
"PATH": "${PATH}:/usr/local/bin"
32+
}
33+
}

.devcontainer-feature/install.sh

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# linctl DevContainer Feature Installation Script
5+
# This script installs linctl CLI for Linear project management
6+
7+
echo "🔧 Installing linctl..."
8+
9+
# Parse options from environment variables
10+
VERSION="${VERSION:-latest}"
11+
INSTALL_METHOD="${INSTALLMETHOD:-release}"
12+
13+
# Detect architecture
14+
ARCH=$(dpkg --print-architecture 2>/dev/null || echo "amd64")
15+
case $ARCH in
16+
"amd64") ARCH="amd64" ;;
17+
"arm64") ARCH="arm64" ;;
18+
"armhf") ARCH="arm64" ;; # Fallback for ARM
19+
*)
20+
echo "⚠️ Unsupported architecture: $ARCH, falling back to source build"
21+
INSTALL_METHOD="source"
22+
;;
23+
esac
24+
25+
# Function to install from GitHub releases
26+
install_from_release() {
27+
echo "📦 Installing linctl from GitHub releases..."
28+
29+
# Get latest release info if version is 'latest'
30+
if [ "$VERSION" = "latest" ]; then
31+
echo "🔍 Fetching latest release information..."
32+
RELEASE_INFO=$(curl -s https://api.github.com/repos/nicholls-inc/linctl/releases/latest)
33+
VERSION=$(echo "$RELEASE_INFO" | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)
34+
35+
if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
36+
echo "❌ Failed to fetch latest release version, falling back to source build"
37+
install_from_source
38+
return
39+
fi
40+
41+
echo "✅ Latest version: $VERSION"
42+
fi
43+
44+
# Construct download URL
45+
BINARY_NAME="linctl-linux-${ARCH}"
46+
DOWNLOAD_URL="https://github.com/nicholls-inc/linctl/releases/download/${VERSION}/${BINARY_NAME}"
47+
CHECKSUMS_URL="https://github.com/nicholls-inc/linctl/releases/download/${VERSION}/checksums.txt"
48+
49+
echo "📥 Downloading linctl binary..."
50+
echo " URL: $DOWNLOAD_URL"
51+
52+
# Create temporary directory
53+
TMP_DIR=$(mktemp -d)
54+
cd "$TMP_DIR"
55+
56+
# Download binary
57+
if ! curl -L -f -o "$BINARY_NAME" "$DOWNLOAD_URL"; then
58+
echo "❌ Failed to download binary, falling back to source build"
59+
rm -rf "$TMP_DIR"
60+
install_from_source
61+
return
62+
fi
63+
64+
# Download and verify checksums if available
65+
if curl -L -f -o checksums.txt "$CHECKSUMS_URL" 2>/dev/null; then
66+
echo "🔐 Verifying checksums..."
67+
if sha256sum -c --ignore-missing checksums.txt; then
68+
echo "✅ Checksum verification passed"
69+
else
70+
echo "❌ Checksum verification failed, falling back to source build"
71+
rm -rf "$TMP_DIR"
72+
install_from_source
73+
return
74+
fi
75+
else
76+
echo "⚠️ Checksums not available, skipping verification"
77+
fi
78+
79+
# Install binary
80+
chmod +x "$BINARY_NAME"
81+
mv "$BINARY_NAME" /usr/local/bin/linctl
82+
83+
# Cleanup
84+
cd /
85+
rm -rf "$TMP_DIR"
86+
87+
echo "✅ linctl installed successfully from release"
88+
}
89+
90+
# Function to install from source
91+
install_from_source() {
92+
echo "🔨 Installing linctl from source..."
93+
94+
# Check if Go is available
95+
if ! command -v go >/dev/null 2>&1; then
96+
echo "❌ Go is not installed. Installing Go..."
97+
98+
# Install Go if not present
99+
GO_VERSION="1.23.11"
100+
GO_ARCH="amd64"
101+
if [ "$ARCH" = "arm64" ]; then
102+
GO_ARCH="arm64"
103+
fi
104+
105+
GO_TARBALL="go${GO_VERSION}.linux-${GO_ARCH}.tar.gz"
106+
curl -L -o "/tmp/${GO_TARBALL}" "https://golang.org/dl/${GO_TARBALL}"
107+
tar -C /usr/local -xzf "/tmp/${GO_TARBALL}"
108+
export PATH="/usr/local/go/bin:$PATH"
109+
rm "/tmp/${GO_TARBALL}"
110+
fi
111+
112+
# Create temporary directory for source build
113+
TMP_DIR=$(mktemp -d)
114+
cd "$TMP_DIR"
115+
116+
# Clone the repository
117+
echo "📥 Cloning linctl repository..."
118+
git clone https://github.com/nicholls-inc/linctl.git .
119+
120+
# Checkout specific version if not latest and not empty
121+
if [ "$VERSION" != "latest" ] && [ -n "$VERSION" ]; then
122+
echo "🔄 Checking out version $VERSION..."
123+
git checkout "$VERSION" || {
124+
echo "❌ Failed to checkout version $VERSION, using main branch"
125+
}
126+
fi
127+
128+
# Build the binary
129+
echo "🔨 Building linctl..."
130+
make deps
131+
make build
132+
133+
# Install binary
134+
chmod +x linctl
135+
mv linctl /usr/local/bin/linctl
136+
137+
# Cleanup
138+
cd /
139+
rm -rf "$TMP_DIR"
140+
141+
echo "✅ linctl built and installed successfully from source"
142+
}
143+
144+
# Main installation logic
145+
case "$INSTALL_METHOD" in
146+
"release")
147+
install_from_release
148+
;;
149+
"source")
150+
install_from_source
151+
;;
152+
*)
153+
echo "❌ Invalid install method: $INSTALL_METHOD"
154+
echo " Valid options: release, source"
155+
exit 1
156+
;;
157+
esac
158+
159+
# Verify installation
160+
if command -v linctl >/dev/null 2>&1; then
161+
echo "🎉 linctl installation completed successfully!"
162+
echo "📋 Version information:"
163+
linctl --version
164+
echo ""
165+
echo "💡 Usage: linctl --help"
166+
echo "🔗 Documentation: https://github.com/nicholls-inc/linctl"
167+
else
168+
echo "❌ linctl installation failed - binary not found in PATH"
169+
exit 1
170+
fi
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"scenarios": [
3+
{
4+
"name": "default",
5+
"description": "Test default installation (latest version from releases)",
6+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
7+
"features": {
8+
"linctl": {}
9+
}
10+
},
11+
{
12+
"name": "source-build",
13+
"description": "Test source build installation",
14+
"image": "mcr.microsoft.com/devcontainers/go:1.23",
15+
"features": {
16+
"linctl": {
17+
"installMethod": "source"
18+
}
19+
}
20+
},
21+
{
22+
"name": "specific-version",
23+
"description": "Test installation with specific version",
24+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
25+
"features": {
26+
"linctl": {
27+
"version": "latest",
28+
"installMethod": "release"
29+
}
30+
}
31+
}
32+
]
33+
}

0 commit comments

Comments
 (0)