From b9effd1e20f8042a091d130dbe6ae8544597e992 Mon Sep 17 00:00:00 2001 From: Allison Thackston <73732028+althack@users.noreply.github.com> Date: Sun, 24 May 2026 16:17:15 -0700 Subject: [PATCH 1/2] Add X11 and Wayland GUI forwarding features --- .github/workflows/release.yaml | 11 ++++++- .github/workflows/test-pr.yaml | 27 ++++++++++++++-- README.md | 9 ++++-- features/src/wayland/README.md | 19 ++++++++++++ .../src/wayland/devcontainer-feature.json | 31 +++++++++++++++++++ features/src/wayland/install.sh | 6 ++++ features/src/x11/README.md | 19 ++++++++++++ features/src/x11/devcontainer-feature.json | 31 +++++++++++++++++++ features/src/x11/install.sh | 6 ++++ features/test/test_all.sh | 8 +++++ features/test/wayland/test.sh | 25 +++++++++++++++ features/test/x11/test.sh | 25 +++++++++++++++ 12 files changed, 211 insertions(+), 6 deletions(-) create mode 100644 features/src/wayland/README.md create mode 100644 features/src/wayland/devcontainer-feature.json create mode 100755 features/src/wayland/install.sh create mode 100644 features/src/x11/README.md create mode 100644 features/src/x11/devcontainer-feature.json create mode 100755 features/src/x11/install.sh create mode 100755 features/test/test_all.sh create mode 100755 features/test/wayland/test.sh create mode 100755 features/test/x11/test.sh diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 00b3feb..4251ce8 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -name: "Release Dev Container Templates" +name: "Release Dev Container Features And Templates" on: workflow_dispatch: @@ -13,6 +13,15 @@ jobs: steps: - uses: actions/checkout@v6 + - name: "Publish Features" + uses: devcontainers/action@v1 + with: + publish-features: "true" + base-path-to-features: "./features/src" + + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: "Publish Templates" uses: devcontainers/action@v1 with: diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index db4f7fb..a975c73 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -1,4 +1,4 @@ -name: "CI - Test Templates" +name: "CI - Test Templates And Features" on: pull_request: @@ -18,6 +18,14 @@ jobs: with: template: "gz" + feature-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Validate feature metadata + run: bash features/test/test_all.sh + gen-docs: if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} runs-on: ubuntu-latest @@ -31,13 +39,18 @@ jobs: ref: ${{ github.head_ref }} token: ${{ secrets.CI_BOT_TOKEN }} - - name: "Publish Templates" + - name: "Generate Template Docs" uses: devcontainers/action@v1 with: - publish-templates: "false" base-path-to-templates: "./templates/src" generate-docs: "true" + - name: "Generate Feature Docs" + uses: devcontainers/action@v1 + with: + base-path-to-features: "./features/src" + generate-docs: "true" + - uses: stefanzweifel/git-auto-commit-action@v7 with: commit_message: Update generated docs @@ -45,6 +58,7 @@ jobs: complete: needs: - gen-docs + - feature-tests - smoke-test if: always() runs-on: ubuntu-latest @@ -52,11 +66,13 @@ jobs: - name: Verify required jobs succeeded env: SMOKE_TEST_RESULT: ${{ needs.smoke-test.result }} + FEATURE_TESTS_RESULT: ${{ needs.feature-tests.result }} GEN_DOCS_RESULT: ${{ needs.gen-docs.result }} run: | set -euo pipefail echo "smoke_test: ${SMOKE_TEST_RESULT}" + echo "feature_tests: ${FEATURE_TESTS_RESULT}" echo "gen_docs: ${GEN_DOCS_RESULT}" if [[ "${SMOKE_TEST_RESULT}" != "success" ]]; then @@ -64,6 +80,11 @@ jobs: exit 1 fi + if [[ "${FEATURE_TESTS_RESULT}" != "success" ]]; then + echo "Required job 'feature_tests' did not succeed." + exit 1 + fi + # gen_docs is skipped for fork PRs by design; treat that as acceptable. if [[ "${GEN_DOCS_RESULT}" != "success" && "${GEN_DOCS_RESULT}" != "skipped" ]]; then echo "Required job 'gen_docs' failed or was cancelled." diff --git a/README.md b/README.md index fcfb820..152f9a1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,12 @@ Devcontainer templates repository focused on robotics and simulation. - `templates/src/gz` +## Included features + +- `features/src/x11` +- `features/src/wayland` + ## Workflows -- `.github/workflows/test-pr.yaml`: smoke tests template changes on pull requests -- `.github/workflows/release.yaml`: publishes templates to GHCR on manual dispatch from `main` +- `.github/workflows/test-pr.yaml`: smoke tests template changes, validates features, and refreshes generated docs on pull requests +- `.github/workflows/release.yaml`: publishes features and templates to GHCR on manual dispatch from `main` diff --git a/features/src/wayland/README.md b/features/src/wayland/README.md new file mode 100644 index 0000000..9e2d3a3 --- /dev/null +++ b/features/src/wayland/README.md @@ -0,0 +1,19 @@ +# Wayland GUI Forwarding (wayland) + +Enable desktop app forwarding from a dev container to your host through Wayland. + +## Example Usage + +```jsonc +{ + "features": { + "ghcr.io/athackst/devcontainer-templates/wayland:0": {} + } +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| softwareGL | Set LIBGL_ALWAYS_SOFTWARE for GPU compatibility. | string | 1 | diff --git a/features/src/wayland/devcontainer-feature.json b/features/src/wayland/devcontainer-feature.json new file mode 100644 index 0000000..c718490 --- /dev/null +++ b/features/src/wayland/devcontainer-feature.json @@ -0,0 +1,31 @@ +{ + "id": "wayland", + "version": "0.1.0", + "name": "Wayland GUI Forwarding", + "description": "Configure container environment and mounts for host Wayland display forwarding.", + "documentationURL": "https://github.com/athackst/devcontainer-templates/tree/main/features/src/wayland", + "licenseURL": "https://github.com/athackst/devcontainer-templates/blob/main/LICENSE", + "options": { + "softwareGL": { + "type": "string", + "default": "1", + "proposals": [ + "0", + "1" + ], + "description": "Set LIBGL_ALWAYS_SOFTWARE for GPU compatibility." + } + }, + "containerEnv": { + "WAYLAND_DISPLAY": "${localEnv:WAYLAND_DISPLAY}", + "XDG_RUNTIME_DIR": "${localEnv:XDG_RUNTIME_DIR}", + "PULSE_SERVER": "${localEnv:PULSE_SERVER}", + "LIBGL_ALWAYS_SOFTWARE": "${feature:softwareGL}" + }, + "mounts": [ + "source=${localEnv:XDG_RUNTIME_DIR},target=${localEnv:XDG_RUNTIME_DIR},type=bind" + ], + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] +} diff --git a/features/src/wayland/install.sh b/features/src/wayland/install.sh new file mode 100755 index 0000000..51daee1 --- /dev/null +++ b/features/src/wayland/install.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Runtime forwarding is configured through feature metadata (containerEnv/mounts). +# Keep install lightweight and deterministic. +echo "Wayland feature metadata configured." diff --git a/features/src/x11/README.md b/features/src/x11/README.md new file mode 100644 index 0000000..bce900f --- /dev/null +++ b/features/src/x11/README.md @@ -0,0 +1,19 @@ +# X11 GUI Forwarding (x11) + +Enable desktop app forwarding from a dev container to your host through X11. + +## Example Usage + +```jsonc +{ + "features": { + "ghcr.io/athackst/devcontainer-templates/x11:0": {} + } +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| softwareGL | Set LIBGL_ALWAYS_SOFTWARE for GPU compatibility. | string | 1 | diff --git a/features/src/x11/devcontainer-feature.json b/features/src/x11/devcontainer-feature.json new file mode 100644 index 0000000..297db48 --- /dev/null +++ b/features/src/x11/devcontainer-feature.json @@ -0,0 +1,31 @@ +{ + "id": "x11", + "version": "0.1.0", + "name": "X11 GUI Forwarding", + "description": "Configure container environment and mounts for host X11 display forwarding.", + "documentationURL": "https://github.com/athackst/devcontainer-templates/tree/main/features/src/x11", + "licenseURL": "https://github.com/athackst/devcontainer-templates/blob/main/LICENSE", + "options": { + "softwareGL": { + "type": "string", + "default": "1", + "proposals": [ + "0", + "1" + ], + "description": "Set LIBGL_ALWAYS_SOFTWARE for GPU compatibility." + } + }, + "containerEnv": { + "DISPLAY": "${localEnv:DISPLAY}", + "XAUTHORITY": "${localEnv:XAUTHORITY}", + "PULSE_SERVER": "${localEnv:PULSE_SERVER}", + "LIBGL_ALWAYS_SOFTWARE": "${feature:softwareGL}" + }, + "mounts": [ + "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind" + ], + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] +} diff --git a/features/src/x11/install.sh b/features/src/x11/install.sh new file mode 100755 index 0000000..8eed45b --- /dev/null +++ b/features/src/x11/install.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Runtime forwarding is configured through feature metadata (containerEnv/mounts). +# Keep install lightweight and deterministic. +echo "X11 feature metadata configured." diff --git a/features/test/test_all.sh b/features/test/test_all.sh new file mode 100755 index 0000000..d1ea3c3 --- /dev/null +++ b/features/test/test_all.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" + +for test_script in "${repo_root}"/features/test/*/test.sh; do + bash "${test_script}" +done diff --git a/features/test/wayland/test.sh b/features/test/wayland/test.sh new file mode 100755 index 0000000..058c89f --- /dev/null +++ b/features/test/wayland/test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +feature_dir="${repo_root}/features/src/wayland" +feature_metadata="${feature_dir}/devcontainer-feature.json" +feature_install="${feature_dir}/install.sh" +feature_readme="${feature_dir}/README.md" + +test -f "${feature_metadata}" +test -f "${feature_install}" +test -f "${feature_readme}" + +jq -e '.id == "wayland"' "${feature_metadata}" >/dev/null +jq -e '.name == "Wayland GUI Forwarding"' "${feature_metadata}" >/dev/null +jq -e '.options.softwareGL.default == "1"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.WAYLAND_DISPLAY == "${localEnv:WAYLAND_DISPLAY}"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.XDG_RUNTIME_DIR == "${localEnv:XDG_RUNTIME_DIR}"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.PULSE_SERVER == "${localEnv:PULSE_SERVER}"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.LIBGL_ALWAYS_SOFTWARE == "${feature:softwareGL}"' "${feature_metadata}" >/dev/null +jq -e '.mounts | index("source=${localEnv:XDG_RUNTIME_DIR},target=${localEnv:XDG_RUNTIME_DIR},type=bind") != null' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.DISPLAY == null' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.XAUTHORITY == null' "${feature_metadata}" >/dev/null + +grep -q 'Wayland feature metadata configured.' "${feature_install}" diff --git a/features/test/x11/test.sh b/features/test/x11/test.sh new file mode 100755 index 0000000..b5d09b1 --- /dev/null +++ b/features/test/x11/test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +feature_dir="${repo_root}/features/src/x11" +feature_metadata="${feature_dir}/devcontainer-feature.json" +feature_install="${feature_dir}/install.sh" +feature_readme="${feature_dir}/README.md" + +test -f "${feature_metadata}" +test -f "${feature_install}" +test -f "${feature_readme}" + +jq -e '.id == "x11"' "${feature_metadata}" >/dev/null +jq -e '.name == "X11 GUI Forwarding"' "${feature_metadata}" >/dev/null +jq -e '.options.softwareGL.default == "1"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.DISPLAY == "${localEnv:DISPLAY}"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.XAUTHORITY == "${localEnv:XAUTHORITY}"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.PULSE_SERVER == "${localEnv:PULSE_SERVER}"' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.LIBGL_ALWAYS_SOFTWARE == "${feature:softwareGL}"' "${feature_metadata}" >/dev/null +jq -e '.mounts | index("source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind") != null' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.WAYLAND_DISPLAY == null' "${feature_metadata}" >/dev/null +jq -e '.containerEnv.XDG_RUNTIME_DIR == null' "${feature_metadata}" >/dev/null + +grep -q 'X11 feature metadata configured.' "${feature_install}" From e63b077edbdc75e791253482b61bfe7d5243964e Mon Sep 17 00:00:00 2001 From: althack <73732028+althack@users.noreply.github.com> Date: Sun, 24 May 2026 23:17:54 +0000 Subject: [PATCH 2/2] Update generated docs --- features/src/wayland/README.md | 17 +++++++++++------ features/src/x11/README.md | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/features/src/wayland/README.md b/features/src/wayland/README.md index 9e2d3a3..30c1a2b 100644 --- a/features/src/wayland/README.md +++ b/features/src/wayland/README.md @@ -1,14 +1,13 @@ + # Wayland GUI Forwarding (wayland) -Enable desktop app forwarding from a dev container to your host through Wayland. +Configure container environment and mounts for host Wayland display forwarding. ## Example Usage -```jsonc -{ - "features": { - "ghcr.io/athackst/devcontainer-templates/wayland:0": {} - } +```json +"features": { + "ghcr.io/althack/devcontainers/wayland:0": {} } ``` @@ -17,3 +16,9 @@ Enable desktop app forwarding from a dev container to your host through Wayland. | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | softwareGL | Set LIBGL_ALWAYS_SOFTWARE for GPU compatibility. | string | 1 | + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/althack/devcontainers/blob/main/features/src/wayland/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/features/src/x11/README.md b/features/src/x11/README.md index bce900f..313e323 100644 --- a/features/src/x11/README.md +++ b/features/src/x11/README.md @@ -1,14 +1,13 @@ + # X11 GUI Forwarding (x11) -Enable desktop app forwarding from a dev container to your host through X11. +Configure container environment and mounts for host X11 display forwarding. ## Example Usage -```jsonc -{ - "features": { - "ghcr.io/athackst/devcontainer-templates/x11:0": {} - } +```json +"features": { + "ghcr.io/althack/devcontainers/x11:0": {} } ``` @@ -17,3 +16,9 @@ Enable desktop app forwarding from a dev container to your host through X11. | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | softwareGL | Set LIBGL_ALWAYS_SOFTWARE for GPU compatibility. | string | 1 | + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/althack/devcontainers/blob/main/features/src/x11/devcontainer-feature.json). Add additional notes to a `NOTES.md`._