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
29 changes: 29 additions & 0 deletions .github/compute-feature-matrix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Usage: compute-feature-matrix.sh <event_name> <changed_cargo-lambda> <changed_lambroll> <changed_ngrok>
# Outputs a JSON array of feature names to GITHUB_OUTPUT (or stdout when GITHUB_OUTPUT is unset).
set -euo pipefail

event_name="${1:-}"
shift

all_features=("cargo-lambda" "lambroll" "ngrok")
declare -A changed=(
["cargo-lambda"]="${1:-false}"
["lambroll"]="${2:-false}"
["ngrok"]="${3:-false}"
)

features=()
for feature in "${all_features[@]}"; do
if [ "$event_name" = "workflow_dispatch" ] || [ "${changed[$feature]}" = "true" ]; then
features+=("$feature")
fi
done

if [ ${#features[@]} -eq 0 ]; then
json="[]"
else
json=$(printf '%s\n' "${features[@]}" | jq -R . | jq -sc .)
fi

echo "features=$json" | tee -a "${GITHUB_OUTPUT:-/dev/stdout}"
45 changes: 39 additions & 6 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,48 @@ on:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
compute-feature-matrix:
runs-on: ubuntu-latest
outputs:
features: ${{ steps.compute.outputs.features }}
steps:
- uses: actions/checkout@v4

- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
cargo-lambda:
- 'src/cargo-lambda/**'
- 'test/cargo-lambda/**'
lambroll:
- 'src/lambroll/**'
- 'test/lambroll/**'
ngrok:
- 'src/ngrok/**'
- 'test/ngrok/**'

- name: "Compute features matrix"
id: compute
run: |
bash .github/compute-feature-matrix.sh \
"${{ github.event_name }}" \
"${{ steps.filter.outputs.cargo-lambda }}" \
"${{ steps.filter.outputs.lambroll }}" \
"${{ steps.filter.outputs.ngrok }}"

test-autogenerated:
needs: compute-feature-matrix
if: needs.compute-feature-matrix.outputs.features != '[]' && needs.compute-feature-matrix.outputs.features != ''
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
features:
- cargo-lambda
- lambroll
features: ${{ fromJson(needs.compute-feature-matrix.outputs.features) }}
baseImage:
- debian:latest
- ubuntu:latest
Expand All @@ -28,13 +61,13 @@ jobs:
run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} .

test-scenarios:
needs: compute-feature-matrix
if: needs.compute-feature-matrix.outputs.features != '[]' && needs.compute-feature-matrix.outputs.features != ''
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
features:
- cargo-lambda
- lambroll
features: ${{ fromJson(needs.compute-feature-matrix.outputs.features) }}
steps:
- uses: actions/checkout@v4

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
>
> - [cargo-lambda](https://www.cargo-lambda.info/)
> - [lambroll](https://github.com/fujiwara/lambroll)
> - [ngrok](https://ngrok.com/)


# How to use
Expand All @@ -13,4 +14,9 @@ note:
- This will install zig to latest version via (ghcr.io/devcontainers-extra/features/zig:1)
- `rust` and `binstall` when not available, will be downloaded

Lambroll: [Readme](src/lambroll/README.md)
Lambroll: [Readme](src/lambroll/README.md)

ngrok: [Readme](src/ngrok/README.md)

- Supports `amd64` (x86_64) and `arm64` (aarch64) architectures
- Defaults to the latest stable release; a specific version can be pinned via the `version` option
33 changes: 33 additions & 0 deletions src/ngrok/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# ngrok

Installs [ngrok](https://ngrok.com/), a secure tunnel to localhost. Supports both `amd64` and `arm64` architectures.

## Options

| Options Id | Description | Type | Default Value |
|-----|-----|-----|-----|
| version | Version of ngrok to install (e.g. `latest`, `stable`, or a specific version like `3.5.0`) | string | latest |

## Usage

Add to your `devcontainer.json`:

```jsonc
{
"features": {
"ghcr.io/tokidoki11/devcontainer-feature/ngrok:1": {}
}
}
```

To install a specific version:

```jsonc
{
"features": {
"ghcr.io/tokidoki11/devcontainer-feature/ngrok:1": {
"version": "3.5.0"
}
}
}
```
13 changes: 13 additions & 0 deletions src/ngrok/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "ngrok",
"id": "ngrok",
"version": "1.0.0",
"description": "Install ngrok - a secure tunnel to localhost. Supports amd64 and arm64 architectures.",
"options": {
"version": {
"type": "string",
"default": "latest",
"description": "Version of ngrok to install (e.g. 'latest', 'stable', or a specific version like '3.5.0')"
}
}
}
57 changes: 57 additions & 0 deletions src/ngrok/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash
set -e

NGROK_VERSION="${VERSION:-"latest"}"

# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
x86_64) NGROK_ARCH="amd64" ;;
aarch64 | arm64) NGROK_ARCH="arm64" ;;
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
esac

# Map "latest" to "stable" for the equinox download URL
if [ "$NGROK_VERSION" = "latest" ]; then
NGROK_VERSION="stable"
fi

# The equinox.io URL path 'bNyj1mQVY4c' is ngrok's stable channel identifier for v3.
# Supported values for NGROK_VERSION: 'stable', or specific versions like '3.5.0'.
DOWNLOAD_URL="https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-${NGROK_VERSION}-linux-${NGROK_ARCH}.tgz"

# 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
}

export DEBIAN_FRONTEND=noninteractive

check_packages curl ca-certificates

echo "Downloading ngrok ${NGROK_VERSION} for ${NGROK_ARCH} from ${DOWNLOAD_URL}"

TEMP_DIR=$(mktemp -d)
if ! curl -sSL --fail "${DOWNLOAD_URL}" -o "${TEMP_DIR}/ngrok.tgz"; then
echo "ERROR: Failed to download ngrok. Please verify the version '${NGROK_VERSION}' is valid and the URL is reachable: ${DOWNLOAD_URL}"
rm -rf "${TEMP_DIR}"
exit 1
fi
if ! tar -xzf "${TEMP_DIR}/ngrok.tgz" -C "${TEMP_DIR}"; then
echo "ERROR: Failed to extract ngrok archive. The downloaded file may be corrupted."
rm -rf "${TEMP_DIR}"
exit 1
fi
install -m 0755 "${TEMP_DIR}/ngrok" /usr/local/bin/ngrok

rm -rf "${TEMP_DIR}"
rm -rf /var/lib/apt/lists/*

echo "ngrok installed successfully"
ngrok version
12 changes: 12 additions & 0 deletions test/ngrok/install_latest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e

source dev-container-features-test-lib

# Feature-specific tests
check "ngrok installed" bash -c "ngrok version"
check "ngrok is executable" which ngrok

# Report results
reportResults
8 changes: 8 additions & 0 deletions test/ngrok/scenarios.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"install_latest": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ngrok": {}
}
}
}
12 changes: 12 additions & 0 deletions test/ngrok/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -e

source dev-container-features-test-lib

# Feature-specific tests
check "ngrok installed" bash -c "ngrok version"
check "ngrok is executable" which ngrok

# Report results
reportResults
Loading