Skip to content
Closed
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
110 changes: 110 additions & 0 deletions .github/actions/setup-compose/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Set up Compose with build input permissions
description: Build Compose from source only when a probe reproduces the external-Dockerfile permission error.

runs:
using: composite
steps:
- name: Probe installed Compose
id: check
shell: bash
env:
# https://github.com/docker/compose/pull/14325 fixes https://github.com/devcontainers/cli/issues/1320.
FIX_COMMIT: 1e1c577eab08ceb5ff0fcf4d8e3cbbc08a34ef35
FIX_VERSION: 5.6.0-dev.1e1c577
run: |
echo "ref=$FIX_COMMIT" >> "$GITHUB_OUTPUT"
echo "version=$FIX_VERSION" >> "$GITHUB_OUTPUT"
docker compose version
probe_dir=$(mktemp -d "$RUNNER_TEMP/compose-probe.XXXXXX")
echo "probe=$probe_dir" >> "$GITHUB_OUTPUT"
image="devcontainers-compose-probe:${probe_dir##*/}"
echo "image=$image" >> "$GITHUB_OUTPUT"
mkdir "$probe_dir/context"
printf 'FROM scratch\nLABEL devcontainers.compose-probe=true\n' > "$probe_dir/Dockerfile"
cat > "$probe_dir/compose.yaml" <<EOF
services:
probe:
image: $image
build:
context: ./context
dockerfile: ../Dockerfile
EOF

if docker compose --project-name compose-probe -f "$probe_dir/compose.yaml" build > "$probe_dir/build.log" 2>&1; then
cat "$probe_dir/build.log"
echo "image-created=true" >> "$GITHUB_OUTPUT"
echo "Compose can build with an external Dockerfile; keeping it."
echo "install=false" >> "$GITHUB_OUTPUT"
else
status=$?
cat "$probe_dir/build.log"
if grep -Fq "additional privileges requested: pass \"--allow=fs.read=$probe_dir/Dockerfile\"" "$probe_dir/build.log"; then
echo "Compose lacks the external-Dockerfile permission fix; building it from source."
echo "install=true" >> "$GITHUB_OUTPUT"
else
echo "::error::Compose probe failed for a reason other than the external-Dockerfile permission error."
exit "$status"
fi
fi

- name: Fetch fixed Compose source
if: steps.check.outputs.install == 'true'
id: source
shell: bash
env:
FIX_COMMIT: ${{ steps.check.outputs.ref }}
run: |
source_dir=$(mktemp -d "$RUNNER_TEMP/compose-source.XXXXXX")
git -C "$source_dir" init
git -C "$source_dir" fetch --depth=1 https://github.com/docker/compose.git "$FIX_COMMIT"
git -C "$source_dir" checkout --detach FETCH_HEAD
test "$(git -C "$source_dir" rev-parse HEAD)" = "$FIX_COMMIT"
echo "path=$source_dir" >> "$GITHUB_OUTPUT"

- uses: actions/setup-go@v6
if: steps.check.outputs.install == 'true'
with:
go-version-file: ${{ steps.source.outputs.path }}/go.mod
cache: false

- name: Build and install fixed Compose
if: steps.check.outputs.install == 'true'
id: install
shell: bash
env:
CGO_ENABLED: '0'
SOURCE_DIR: ${{ steps.source.outputs.path }}
FIX_VERSION: ${{ steps.check.outputs.version }}
PROBE_DIR: ${{ steps.check.outputs.probe }}
run: |
cd "$SOURCE_DIR"
# Preserve the CLI's Compose version gates for this unreleased source build.
go build -trimpath \
-ldflags "-s -w -X github.com/docker/compose/v5/internal.Version=v$FIX_VERSION" \
-o docker-compose ./cmd
install -D -m 755 docker-compose "${DOCKER_CONFIG:-$HOME/.docker}/cli-plugins/docker-compose"
version=$(docker compose version --short)
if [[ "${version#v}" != "$FIX_VERSION" ]]; then
echo "::error::Expected Compose $FIX_VERSION after installation, got $version"
exit 1
fi
docker compose version
docker compose --project-name compose-probe -f "$PROBE_DIR/compose.yaml" build
echo "image-created=true" >> "$GITHUB_OUTPUT"

- name: Clean up Compose probe
if: always() && steps.check.outputs.probe != ''
shell: bash
env:
PROBE_DIR: ${{ steps.check.outputs.probe }}
PROBE_IMAGE: ${{ steps.check.outputs.image }}
IMAGE_CREATED: ${{ steps.check.outputs.image-created == 'true' || steps.install.outputs.image-created == 'true' }}
run: |
rm -f -- "$PROBE_DIR/Dockerfile" "$PROBE_DIR/compose.yaml" "$PROBE_DIR/build.log"
if [[ -d "$PROBE_DIR/context" ]]; then
rmdir -- "$PROBE_DIR/context"
fi
rmdir -- "$PROBE_DIR"
if [[ "$IMAGE_CREATED" == 'true' ]]; then
docker image rm "$PROBE_IMAGE"
fi
1 change: 1 addition & 0 deletions .github/workflows/dev-containers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ jobs:
fi
cat "$DAEMON_JSON"
sudo systemctl restart docker
- uses: ./.github/actions/setup-compose
- name: Tools Info
run: |
docker info
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test-docker-v29.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
sudo VERSION=29.0.0 sh get-docker.sh
sudo systemctl restart docker

- uses: ./.github/actions/setup-compose

- name: Verify Docker version, Install and Test
run: |
# Verify
Expand Down
Loading