Skip to content

Commit 651421a

Browse files
author
Jacob Woffenden
committed
Add base image
Add images workflow Add path-filter generator Signed-off-by: Jacob Woffenden <[email protected]>
1 parent 33de53d commit 651421a

File tree

6 files changed

+238
-0
lines changed

6 files changed

+238
-0
lines changed

.github/workflows/images.yml

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
name: Images
3+
4+
on:
5+
pull_request:
6+
branches:
7+
- main
8+
paths:
9+
- images/**
10+
11+
permissions: {}
12+
13+
jobs:
14+
detect-changes:
15+
name: Detect Changes
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
outputs:
20+
images: ${{ steps.detect_changes.outputs.changes }}
21+
steps:
22+
- name: Checkout
23+
id: checkout
24+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
25+
26+
- name: Build path-filters file
27+
id: build_path_filters
28+
run: bash scripts/path-filter/configuration-generator.sh images
29+
30+
- name: Detect changes
31+
id: detect_changes
32+
uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
33+
with:
34+
filters: .github/path-filter/images.yml
35+
36+
build-and-test:
37+
needs: [detect-changes]
38+
if: ${{ needs.detect-changes.outputs.images != '[]' }}
39+
name: Build and Test
40+
runs-on: ubuntu-latest
41+
steps:
42+
strategy:
43+
fail-fast: false
44+
matrix:
45+
image: ${{ fromJson(needs.detect-changes.outputs.images) }}
46+
steps:
47+
- name: Checkout
48+
id: checkout
49+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
50+
51+
- name: Build and Test
52+
id: build_and_test
53+
run: |
54+
bash scripts/build-and-test.sh ${{ matrix.image }}

images/base/Containerfile

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04
2+
3+
COPY --chown=nobody:nobody --chmod=0755 src/usr/local/bin/devcontainer-utils /usr/local/bin/devcontainer-utils
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env bash
2+
3+
##################################################
4+
# Environment
5+
##################################################
6+
7+
export DEBIAN_FRONTEND="noninteractive"
8+
9+
##################################################
10+
# Function
11+
##################################################
12+
13+
logger() {
14+
local type="${1}"
15+
local message="${2}"
16+
timestamp=$(date --rfc-3339=seconds)
17+
local timestamp
18+
19+
case "${type}" in
20+
err | error)
21+
echo "${timestamp} [ERROR] ${message}"
22+
;;
23+
info | information)
24+
echo "${timestamp} [INFO] ${message}"
25+
;;
26+
warn | warning)
27+
echo "${timestamp} [WARN] ${message}"
28+
;;
29+
esac
30+
}
31+
32+
get_system_architecture() {
33+
systemArchitecture="$(uname -m)"
34+
export systemArchitecture
35+
36+
case ${systemArchitecture} in
37+
x86_64)
38+
logger "info" "Architecture is x86_64"
39+
export ARCHITECTURE="amd64"
40+
;;
41+
aarch64 | armv8*)
42+
logger "info" "Architecture is aarch64 or armv8"
43+
export ARCHITECTURE="arm64"
44+
;;
45+
*)
46+
logger "error" "Architecture ${systemArchitecture} is not supported"
47+
exit 1
48+
;;
49+
esac
50+
}
51+
52+
get_github_latest_tag() {
53+
local repository="${1}"
54+
55+
repositoryLatestTag="$(curl --silent https://api.github.com/repos/"${repository}"/releases/latest | jq -r '.tag_name')"
56+
export repositoryLatestTag
57+
58+
repositoryLatestTagStripV=${repositoryLatestTag//v/}
59+
60+
logger "info" "GitHub latest tag for ${repository} is ${repositoryLatestTag}"
61+
export GITHUB_LATEST_TAG="${repositoryLatestTag}"
62+
export GITHUB_LATEST_TAG_STRIP_V="${repositoryLatestTagStripV}"
63+
}
64+
65+
apt_install() {
66+
local packages="${1}"
67+
68+
apt-get update --yes
69+
70+
apt-get install --yes --no-install-recommends "${packages}"
71+
72+
apt-get clean
73+
74+
rm --force --recursive /var/lib/apt/lists/*
75+
}
76+
77+
pip_install() {
78+
local packages="${1}"
79+
80+
python3 -m pip install --no-cache-dir --upgrade "${packages}"
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
schemaVersion: 2.0.0
3+
4+
commandTests:
5+
- name: "vscode user"
6+
command: "id"
7+
args: ["--user", "vscode"]
8+
expectedOutput: ["1000"]
9+
10+
- name: "vscode group"
11+
command: "id"
12+
args: ["--group", "vscode"]
13+
expectedOutput: ["1000"]
14+
15+
fileExistenceTests:
16+
- name: "devcontainer-utils"
17+
path: "/usr/local/bin/devcontainer-utils"
18+
shouldExist: true
19+
permissions: "-rwxr-xr-x" # 0755
20+
uid: 65534
21+
gid: 65534
22+
isExecutableBy: "any"

scripts/images/build-and-test.sh

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
3+
# 1. Build image
4+
5+
# 2. Run GoogleContainerTools/container-structure-test
6+
7+
IMAGE="${1}"
8+
IMAGE_DIRECTORY="images/${IMAGE}"
9+
IMAGE_TAG="ghcr.io/ministryofjustice/devcontainer-${IMAGE}:local"
10+
CONTAINER_STRUCTURE_TEST_IMAGE="gcr.io/gcp-runtimes/container-structure-test:latest"
11+
12+
echo "Building [ ${IMAGE} ] as [ ${IMAGE_TAG} ]"
13+
14+
docker build --file "${IMAGE_DIRECTORY}/Containerfile" --tag "${IMAGE_TAG}" "${IMAGE_DIRECTORY}"
15+
16+
if [[ -f "${IMAGE_DIRECTORY}/test/container-structure-test.yml" ]]; then
17+
echo "Running container structure test for [ ${IMAGE_TAG} ]"
18+
19+
docker run --rm \
20+
--volume /var/run/docker.sock:/var/run/docker.sock \
21+
--volume "${PWD}:/workspace" \
22+
--workdir /workspace \
23+
"${CONTAINER_STRUCTURE_TEST_IMAGE}" \
24+
test --image "${IMAGE_TAG}" --config "/workspace/${IMAGE_DIRECTORY}/test/container-structure-test.yml"
25+
fi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
3+
MODE="${1}"
4+
5+
case ${MODE} in
6+
features)
7+
PATH_FILTER_CONFIGURATION_FILE=".github/path-filters/features.yml"
8+
SEARCH_PATTERN="devcontainer-feature.json"
9+
SKIP_FILE=".feature-path-filter-ignore"
10+
;;
11+
images)
12+
PATH_FILTER_CONFIGURATION_FILE=".github/path-filters/images.yml"
13+
SEARCH_PATTERN="*Containerfile*"
14+
SKIP_FILE=".image-path-filter-ignore"
15+
;;
16+
*)
17+
echo "Usage: ${0} [features|images]"
18+
exit 1
19+
;;
20+
esac
21+
22+
folders=$(find . -type f -name "${SEARCH_PATTERN}" -exec dirname {} \; | sort -h | uniq | cut -c 3-)
23+
export folders
24+
25+
echo "=== Folders ==="
26+
echo "${folders}"
27+
28+
echo "Generating ${PATH_FILTER_CONFIGURATION_FILE}"
29+
cat >"${PATH_FILTER_CONFIGURATION_FILE}" <<EOL
30+
---
31+
# This file is auto-generated by running the below command, do not manually amend.
32+
# bash scripts/path-filter/configuration-generator.sh ${MODE}
33+
34+
EOL
35+
36+
for folder in ${folders}; do
37+
38+
if [[ -f "${folder}/${SKIP_FILE}" ]]; then
39+
echo "Ignoring ${folder}"
40+
continue
41+
fi
42+
43+
if [[ "${MODE}" == "terraform" ]]; then
44+
baseName=$(echo "${folder}" | sed 's|/|-|g' | sed 's|terraform-||')
45+
else
46+
baseName=$(basename "${folder}")
47+
fi
48+
49+
{
50+
printf "%s: %s/**\n" "${baseName}" "${folder}"
51+
} >>"${PATH_FILTER_CONFIGURATION_FILE}"
52+
53+
done

0 commit comments

Comments
 (0)