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
74 changes: 74 additions & 0 deletions .github/workflows/devcontainer-feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Dev Container Feature

# Tests and publishes ghcr.io/queryahub/features/querya-ext-tester
# (devcontainer-features/src). The tester is a glibc binary, so only
# Debian-family bases are tested. Pull requests only test; the Feature is pushed
# from main/dev or by hand.
on:
push:
branches: [main, dev]
paths:
- devcontainer-features/**
- .github/workflows/devcontainer-feature.yml
pull_request:
paths:
- devcontainer-features/**
- .github/workflows/devcontainer-feature.yml
workflow_dispatch:

permissions:
contents: read

concurrency:
group: devcontainer-feature-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Test querya-ext-tester Feature (${{ matrix.base }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
base:
- mcr.microsoft.com/devcontainers/base:ubuntu
- mcr.microsoft.com/devcontainers/base:debian
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Install the Dev Containers CLI
run: npm install -g @devcontainers/cli@0.80.0
- name: Autogenerated tests (default options)
run: |
devcontainer features test \
--features querya-ext-tester \
--base-image "${{ matrix.base }}" \
--project-folder devcontainer-features
- name: Scenarios
if: matrix.base == 'mcr.microsoft.com/devcontainers/base:ubuntu'
run: |
devcontainer features test \
--features querya-ext-tester \
--skip-autogenerated \
--project-folder devcontainer-features

publish:
name: Publish Feature
needs: test
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
- uses: devcontainers/action@v1
with:
publish-features: "true"
base-path-to-features: ./devcontainer-features/src
features-namespace: queryahub/features
generate-docs: "false"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "querya-ext-tester",
"version": "1.0.0",
"name": "Querya extension tester",
"description": "Installs querya-ext-tester, the headless test runner for Querya database-driver extensions, from a Querya Desktop release (SHA-256 checked).",
"documentationURL": "https://github.com/QueryaHub/Querya-Desktop/blob/main/docs/extension-testing.md",
"options": {
"version": {
"type": "string",
"default": "latest",
"proposals": ["latest", "0.4.19"],
"description": "Querya Desktop release to take the tester from (for example 0.4.19), or latest. Must be 0.4.19 or newer."
}
},
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
69 changes: 69 additions & 0 deletions devcontainer-features/src/querya-ext-tester/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Installs querya-ext-tester from a Querya Desktop release and checks the
# archive against the SHA256SUMS.txt published with that release.
set -euo pipefail

REPO="QueryaHub/Querya-Desktop"
MIN_VERSION="0.4.19" # earlier testers ignored the exit code of main()
REQUESTED="${VERSION:-latest}"
DEST="${QUERYA_EXT_TESTER_DEST:-/usr/local/bin/querya-ext-tester}"

fail() { echo "querya-ext-tester feature: $*" >&2; exit 1; }

ensure_tools() {
local missing=()
for tool in curl tar sha256sum; do
command -v "$tool" >/dev/null 2>&1 || missing+=("$tool")
done
[ ${#missing[@]} -eq 0 ] && return 0
if command -v apt-get >/dev/null 2>&1; then
apt-get update -y && apt-get install -y --no-install-recommends curl ca-certificates tar coreutils
elif command -v apk >/dev/null 2>&1; then
apk add --no-cache curl ca-certificates tar coreutils
elif command -v dnf >/dev/null 2>&1; then
dnf install -y curl ca-certificates tar coreutils
else
fail "missing ${missing[*]} and no known package manager to install them"
fi
}

case "$(uname -s)-$(uname -m)" in
Linux-x86_64) TARGET="linux-x64" ;;
*) fail "only Linux x86_64 is released ($(uname -s)-$(uname -m))" ;;
esac

ensure_tools

if [ "$REQUESTED" = "latest" ]; then
# The redirect avoids the API and its unauthenticated rate limit.
TAG="$(curl -fsSLI -o /dev/null -w '%{url_effective}' "https://github.com/${REPO}/releases/latest")"
TAG="${TAG##*/}"
else
TAG="${REQUESTED#v}"
fi
VERSION_NUMBER="${TAG#v}"
[[ "$VERSION_NUMBER" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail "cannot read a version from '${TAG}'"

if [ "$(printf '%s\n%s\n' "$MIN_VERSION" "$VERSION_NUMBER" | sort -V | head -n1)" != "$MIN_VERSION" ]; then
fail "querya-ext-tester ${VERSION_NUMBER} is older than ${MIN_VERSION}; its exit codes are not reliable"
fi

ASSET="querya-ext-tester-v${VERSION_NUMBER}-${TARGET}.tar.gz"
BASE="https://github.com/${REPO}/releases/download/${TAG}"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT

echo "Downloading ${ASSET} from release ${TAG}"
curl -fsSL -o "${WORK}/${ASSET}" "${BASE}/${ASSET}" || fail "cannot download ${BASE}/${ASSET}"
curl -fsSL -o "${WORK}/SHA256SUMS.txt" "${BASE}/SHA256SUMS.txt" || fail "cannot download ${BASE}/SHA256SUMS.txt"

EXPECTED="$(grep " ${ASSET}\$" "${WORK}/SHA256SUMS.txt" | cut -d' ' -f1 || true)"
[ -n "$EXPECTED" ] || fail "${ASSET} is not listed in SHA256SUMS.txt of ${TAG}"
ACTUAL="$(sha256sum "${WORK}/${ASSET}" | cut -d' ' -f1)"
[ "$EXPECTED" = "$ACTUAL" ] || fail "checksum mismatch for ${ASSET}"

tar -xzf "${WORK}/${ASSET}" -C "$WORK"
install -m 0755 "${WORK}/querya-ext-tester" "$DEST"

"$DEST" --help | grep -q "Usage: querya-ext-tester" || fail "installed binary does not run"
echo "Installed querya-ext-tester ${VERSION_NUMBER}"
9 changes: 9 additions & 0 deletions devcontainer-features/test/querya-ext-tester/pinned.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Scenario "pinned": version 0.4.19, the oldest supported tester.
set -e
source dev-container-features-test-lib

check "tester is on PATH" command -v querya-ext-tester
check "tester prints usage" bash -c 'querya-ext-tester --help | grep -q "Usage: querya-ext-tester"'

reportResults
8 changes: 8 additions & 0 deletions devcontainer-features/test/querya-ext-tester/scenarios.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"pinned": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"querya-ext-tester": { "version": "0.4.19" }
}
}
}
10 changes: 10 additions & 0 deletions devcontainer-features/test/querya-ext-tester/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Default scenario: the Feature with its default options (latest release).
set -e
source dev-container-features-test-lib

check "tester is on PATH" command -v querya-ext-tester
check "tester prints usage" bash -c 'querya-ext-tester --help | grep -q "Usage: querya-ext-tester"'
check "tester fails on an empty directory" bash -c 'd=$(mktemp -d); ! querya-ext-tester "$d" --no-color'

reportResults
19 changes: 19 additions & 0 deletions docs/extension-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,25 @@ the container with `--security-opt seccomp=unconfined` (and, on hosts that
restrict namespaces with AppArmor, `--security-opt apparmor=unconfined`), or
run the tester directly on the CI runner with the action below.

## Dev Container Feature

In a dev container the tester can be installed as a Feature. It downloads the
release archive, checks it against `SHA256SUMS.txt` and puts `querya-ext-tester`
in `PATH` (Linux x86_64, Debian-family images):

```json
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/queryahub/features/querya-ext-tester:1": { "version": "latest" }
}
}
```

`version` is a Querya Desktop release (`0.4.19`) or `latest`. Releases before
0.4.19 are refused: their exit codes were not reliable. The source is in
`devcontainer-features/src/querya-ext-tester`.

## GitHub Actions

This repository contains a composite action in
Expand Down
Loading