Skip to content

Commit 1460d2d

Browse files
authored
Merge pull request #1 from althack/new/gz
Add gz template
2 parents e51cdb8 + ebe594f commit 1460d2d

File tree

11 files changed

+331
-2
lines changed

11 files changed

+331
-2
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: 'Smoke test'
2+
description: Run a smoke test on built templates
3+
inputs:
4+
template:
5+
description: 'Template id under templates/src to test'
6+
required: true
7+
8+
runs:
9+
using: composite
10+
steps:
11+
- name: Checkout main
12+
id: checkout_release
13+
uses: actions/checkout@v6
14+
15+
- name: Build template
16+
id: build_template
17+
shell: bash
18+
run: ${{ github.action_path }}/build.sh ${{ inputs.template }}
19+
20+
- name: Test template
21+
id: test_template
22+
shell: bash
23+
run: ${{ github.action_path }}/test.sh ${{ inputs.template }}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
TEMPLATE_ID="$1"
3+
4+
set -e
5+
6+
shopt -s dotglob
7+
8+
SRC_DIR="/tmp/${TEMPLATE_ID}"
9+
cp -R "templates/src/${TEMPLATE_ID}" "${SRC_DIR}"
10+
11+
pushd "${SRC_DIR}"
12+
13+
# Configure templates only if `devcontainer-template.json` contains the `options` property.
14+
OPTION_PROPERTY=( $(jq -r '.options' devcontainer-template.json) )
15+
16+
if [ "${OPTION_PROPERTY}" != "" ] && [ "${OPTION_PROPERTY}" != "null" ] ; then
17+
OPTIONS=( $(jq -r '.options | keys[]' devcontainer-template.json) )
18+
19+
if [ "${OPTIONS[0]}" != "" ] && [ "${OPTIONS[0]}" != "null" ] ; then
20+
echo "(!) Configuring template options for '${TEMPLATE_ID}'"
21+
for OPTION in "${OPTIONS[@]}"
22+
do
23+
OPTION_KEY="\${templateOption:$OPTION}"
24+
OPTION_VALUE=$(jq -r ".options | .${OPTION} | .default" devcontainer-template.json)
25+
26+
if [ "${OPTION_VALUE}" = "" ] || [ "${OPTION_VALUE}" = "null" ] ; then
27+
echo "Template '${TEMPLATE_ID}' is missing a default value for option '${OPTION}'"
28+
exit 1
29+
fi
30+
31+
echo "(!) Replacing '${OPTION_KEY}' with '${OPTION_VALUE}'"
32+
OPTION_VALUE_ESCAPED=$(sed -e 's/[]\/$*.^[]/\\&/g' <<<"${OPTION_VALUE}")
33+
find ./ -type f -print0 | xargs -0 sed -i "s/${OPTION_KEY}/${OPTION_VALUE_ESCAPED}/g"
34+
done
35+
fi
36+
fi
37+
38+
popd
39+
40+
TEST_DIR="test/${TEMPLATE_ID}"
41+
if [ -d "${TEST_DIR}" ] ; then
42+
echo "(*) Copying test folder"
43+
DEST_DIR="${SRC_DIR}/test-project"
44+
mkdir -p ${DEST_DIR}
45+
cp -Rp ${TEST_DIR}/* ${DEST_DIR}
46+
cp -Rp test/test-utils/* ${DEST_DIR}
47+
fi
48+
49+
export DOCKER_BUILDKIT=1
50+
echo "(*) Installing @devcontainer/cli"
51+
npm install -g @devcontainers/cli
52+
53+
echo "Building Dev Container"
54+
ID_LABEL="test-container=${TEMPLATE_ID}"
55+
devcontainer up --id-label ${ID_LABEL} --workspace-folder "${SRC_DIR}"

.github/actions/smoke-test/test.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
TEMPLATE_ID="$1"
3+
set -e
4+
5+
SRC_DIR="/tmp/${TEMPLATE_ID}"
6+
echo "Running Smoke Test"
7+
8+
ID_LABEL="test-container=${TEMPLATE_ID}"
9+
devcontainer exec --workspace-folder "${SRC_DIR}" --id-label ${ID_LABEL} /bin/sh -c 'set -e && if [ -f "test-project/test.sh" ]; then cd test-project && if [ "$(id -u)" = "0" ]; then chmod +x test.sh; else sudo chmod +x test.sh; fi && ./test.sh; else ls -a; fi'
10+
11+
# Clean up
12+
docker rm -f $(docker container ls -f "label=${ID_LABEL}" -q)
13+
rm -rf "${SRC_DIR}"

.github/workflows/release.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: "Release Dev Container Templates"
2+
on:
3+
workflow_dispatch:
4+
5+
jobs:
6+
deploy:
7+
if: ${{ github.ref == 'refs/heads/main' }}
8+
runs-on: ubuntu-latest
9+
permissions:
10+
packages: write
11+
contents: write
12+
pull-requests: write
13+
steps:
14+
- uses: actions/checkout@v6
15+
16+
- name: "Publish Templates"
17+
uses: devcontainers/action@v1
18+
with:
19+
publish-templates: "true"
20+
base-path-to-templates: "./templates/src"
21+
22+
env:
23+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test-pr.yaml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: "CI - Test Templates"
2+
on:
3+
pull_request:
4+
5+
jobs:
6+
smoke-test:
7+
runs-on: ubuntu-latest
8+
permissions:
9+
# Give the default GITHUB_TOKEN write permission to commit and push the
10+
# added or changed files to the repository.
11+
contents: write
12+
steps:
13+
- uses: actions/checkout@v6
14+
15+
- name: Smoke test for "gz"
16+
id: smoke_test
17+
uses: ./.github/actions/smoke-test
18+
with:
19+
template: "gz"
20+
21+
gen-docs:
22+
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
23+
runs-on: ubuntu-latest
24+
permissions:
25+
# Give the default GITHUB_TOKEN write permission to commit and push the
26+
# added or changed files to the repository.
27+
contents: write
28+
steps:
29+
- uses: actions/checkout@v6
30+
with:
31+
ref: ${{ github.head_ref }}
32+
token: ${{ secrets.CI_BOT_TOKEN }}
33+
34+
- name: "Publish Templates"
35+
uses: devcontainers/action@v1
36+
with:
37+
publish-templates: "false"
38+
base-path-to-templates: "./templates/src"
39+
generate-docs: "true"
40+
41+
- uses: stefanzweifel/git-auto-commit-action@v7
42+
with:
43+
commit_message: Update generated docs
44+
45+
complete:
46+
needs:
47+
- gen-docs
48+
- smoke-test
49+
if: always()
50+
runs-on: ubuntu-latest
51+
steps:
52+
- name: Verify required jobs succeeded
53+
env:
54+
SMOKE_TEST_RESULT: ${{ needs.smoke-test.result }}
55+
GEN_DOCS_RESULT: ${{ needs.gen-docs.result }}
56+
run: |
57+
set -euo pipefail
58+
59+
echo "smoke_test: ${SMOKE_TEST_RESULT}"
60+
echo "gen_docs: ${GEN_DOCS_RESULT}"
61+
62+
if [[ "${SMOKE_TEST_RESULT}" != "success" ]]; then
63+
echo "Required job 'smoke_test' did not succeed."
64+
exit 1
65+
fi
66+
67+
# gen_docs is skipped for fork PRs by design; treat that as acceptable.
68+
if [[ "${GEN_DOCS_RESULT}" != "success" && "${GEN_DOCS_RESULT}" != "skipped" ]]; then
69+
echo "Required job 'gen_docs' failed or was cancelled."
70+
exit 1
71+
fi
72+
73+
echo "All required jobs completed successfully."

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.tmp/

.vscode/tasks.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "Local Smoke Test GZ: Build",
6+
"type": "process",
7+
"command": ".github/actions/smoke-test/build.sh",
8+
"args": [
9+
"gz"
10+
],
11+
"options": {
12+
"cwd": "${workspaceFolder}",
13+
"env": {
14+
"TEMPLATE_ARGS": "{\"distro\":\"jetty\",\"imageVariant\":\"base\"}"
15+
}
16+
},
17+
"problemMatcher": []
18+
},
19+
{
20+
"label": "Local Smoke Test GZ: Assert",
21+
"dependsOrder": "sequence",
22+
"dependsOn": [
23+
"Local Smoke Test GZ: Build"
24+
],
25+
"type": "process",
26+
"command": ".github/actions/smoke-test/test.sh",
27+
"args": [
28+
"gz"
29+
],
30+
"options": {
31+
"cwd": "${workspaceFolder}"
32+
},
33+
"problemMatcher": []
34+
},
35+
{
36+
"label": "Local Smoke Test GZ",
37+
"dependsOrder": "sequence",
38+
"dependsOn": [
39+
"Local Smoke Test GZ: Build",
40+
"Local Smoke Test GZ: Assert"
41+
],
42+
"problemMatcher": []
43+
}
44+
]
45+
}

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
1-
# ros2-devcontainer-templates
2-
ROS2 devcontainer templates
1+
# devcontainers
2+
3+
Devcontainer templates repository focused on robotics and simulation.
4+
5+
## Included template
6+
7+
- `templates/src/gz`
8+
9+
## Workflows
10+
11+
- `.github/workflows/test-pr.yaml`: smoke tests template changes on pull requests
12+
- `.github/workflows/release.yaml`: publishes templates to GHCR on manual dispatch from `main`
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "Gazebo",
3+
"image": "althack/gz:${templateOption:distro}-${templateOption:imageVariant}",
4+
"remoteUser": "ros",
5+
"updateRemoteUserUID": true,
6+
"containerEnv": {
7+
"GZ_VERSION": "${templateOption:distro}"
8+
},
9+
"runArgs": [
10+
"--network=host",
11+
"--ipc=host",
12+
"--cap-add=SYS_PTRACE",
13+
"--security-opt=seccomp:unconfined",
14+
"--security-opt=apparmor:unconfined"
15+
],
16+
"customizations": {
17+
"vscode": {
18+
"extensions": [
19+
"ms-vscode.cpptools",
20+
"ms-python.python",
21+
"twxs.cmake",
22+
"redhat.vscode-yaml"
23+
]
24+
}
25+
}
26+
}

templates/src/gz/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
# Gazebo (gz)
3+
4+
Gazebo development environment.
5+
6+
## Options
7+
8+
| Options Id | Description | Type | Default Value |
9+
|-----|-----|-----|-----|
10+
| distro | Gazebo distribution to use. | string | jetty |
11+
| imageVariant | Container image variant to use for this Gazebo distro. | string | base |
12+
13+
14+
15+
---
16+
17+
_Note: This file was auto-generated from the [devcontainer-template.json](https://github.com/althack/devcontainers/blob/main/templates/src/gz/devcontainer-template.json). Add additional notes to a `NOTES.md`._

0 commit comments

Comments
 (0)