Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ jobs:
- zizmor
- open-code-review
- skillspector
- herdr
baseImage:
- debian:latest
- ubuntu:latest
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ This repository contains a _collection_ of Features.
| zizmor | https://github.com/zizmorcore/zizmor | Static security analysis for GitHub Actions workflows. |
| open-code-review | https://github.com/alibaba/open-code-review | CLI-oriented code review tool for diffs with deterministic checks plus optional LLM review. |
| SkillSpector | https://github.com/NVIDIA/SkillSpector | Standalone security scanner for local AI-agent skill/config files; useful only if you want an AI-dev-security feature. |
| herdr | https://github.com/ogulcancelik/herdr | Fast, cross-platform CLI tool distributed as a static binary via GitHub releases. |



Expand Down Expand Up @@ -752,3 +753,20 @@ Running `skillspector --version` inside the built container will print the versi
skillspector --version
```


### `herdr`

Running `herdr --version` inside the built container will print the version of herdr.

```jsonc
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/jsburckhardt/devcontainer-features/herdr:1": {}
}
}
```

```bash
herdr --version
```
13 changes: 13 additions & 0 deletions src/herdr/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "herdr",
"id": "herdr",
"version": "1.0.0",
"description": "herdr is a fast, cross-platform CLI tool from ogulcancelik/herdr distributed as a static binary via GitHub releases.",
"options": {
"version": {
"type": "string",
"default": "latest",
"description": "Version of herdr to install (e.g. 'latest' or a specific tag like 'v0.7.3')."
}
}
}
86 changes: 86 additions & 0 deletions src/herdr/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bash

set -e

# Variables
REPO_OWNER="ogulcancelik"
REPO_NAME="herdr"
BINARY_NAME="herdr"

# Root check
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/*

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
}

# Ensure required packages are installed
check_packages curl ca-certificates jq tar

# Function to get the latest version from GitHub API
get_latest_version() {
LATEST_URL="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases/latest"
curl -s "$LATEST_URL" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
}

# Resolve version
if [ -z "${VERSION:-}" ] || [ "${VERSION}" = "latest" ]; then
VERSION="$(get_latest_version)"
if [ -z "$VERSION" ]; then
echo "Failed to resolve latest version from GitHub API." >&2
exit 1
fi
echo "No version provided or 'latest' specified, installing the latest version: $VERSION"
else
echo "Installing version from environment variable: $VERSION"
fi

# Determine OS
OS_RAW="$(uname -s)"
case "$OS_RAW" in
Linux) OS="linux" ;;
Darwin) OS="macos" ;;
*) echo "Unsupported OS: $OS_RAW" >&2; exit 1 ;;
esac

# Determine architecture
ARCH_RAW="$(uname -m)"
case "$ARCH_RAW" in
x86_64|amd64) ARCH="x86_64" ;;
aarch64|arm64) ARCH="aarch64" ;;
*) echo "Unsupported architecture: $ARCH_RAW" >&2; exit 1 ;;
esac

ASSET_NAME="${BINARY_NAME}-${OS}-${ARCH}"
DOWNLOAD_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/releases/download/${VERSION}/${ASSET_NAME}"

# Download binary
TMP_DIR="$(mktemp -d)"
cd "$TMP_DIR"

echo "Downloading $BINARY_NAME from $DOWNLOAD_URL"
curl -sSL -o "$BINARY_NAME" "$DOWNLOAD_URL"

chmod +x "$BINARY_NAME"
mv "$BINARY_NAME" /usr/local/bin/

# Cleanup
cd /
rm -rf "$TMP_DIR"
rm -rf /var/lib/apt/lists/*

# Verify installation
echo "Verifying installation"
"$BINARY_NAME" --version
1 change: 1 addition & 0 deletions test/_global/all-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ check "actionlint" actionlint --version
check "zizmor" zizmor --version
check "open-code-review" opencodereview --version
check "skillspector" skillspector --version
check "herdr" herdr --version

reportResults
9 changes: 9 additions & 0 deletions test/_global/herdr-specific-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

set -e

source dev-container-features-test-lib

check "herdr with specific version" /bin/bash -c "herdr --version | grep '0.7.3'"

reportResults
11 changes: 10 additions & 1 deletion test/_global/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"actionlint": {},
"zizmor": {},
"open-code-review": {},
"skillspector": {}
"skillspector": {},
"herdr": {}
}
},
"flux-specific-version": {
Expand Down Expand Up @@ -354,5 +355,13 @@
"version": "8f37cfa1ebc2"
}
}
},
"herdr-specific-version": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"herdr": {
"version": "v0.7.3"
}
}
}
}
9 changes: 9 additions & 0 deletions test/herdr/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

set -e

source dev-container-features-test-lib

check "herdr" herdr --version

reportResults
Loading