diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd14824..7ddea1f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -156,6 +156,131 @@ jobs: test -f debian/artifacts/test_1_amd64.buildinfo test -f debian/artifacts/test_1_amd64.changes + extra-repo-keys-ascii: + needs: [single-package] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: download-keys + run: | + docker run --detach --mount="type=bind,src=${{ github.workspace }},dst=/workspace" --name=download-cont --rm --workdir=/workspace debian:stable-slim tail -f /dev/null + docker exec download-cont apt-get update + docker exec --user="$(id -u):$(id -g)" download-cont apt-get download debian-archive-keyring + docker stop --time=1 download-cont + dpkg-deb --extract debian-archive-keyring_*.deb debian-archive-keyring + { + printf 'debian-archive-keys<>"$GITHUB_OUTPUT" + - uses: ./ + env: + DEB_BUILD_OPTIONS: noautodbgsym + with: + buildpackage-opts: --build=binary --no-sign + docker-image: test/Dockerfile_extra-repo-keys + # An output value instead of an environment variable is used here to + # not interfere with Docker’s environment down the line. + extra-repo-keys: ${{ steps.download-keys.outputs.debian-archive-keys }} + source-dir: test + - run: | + dpkg --info debian/artifacts/test_1_amd64.deb + dpkg --contents debian/artifacts/test_1_amd64.deb | grep ./usr/bin/mybin + test -f debian/artifacts/test_1_amd64.buildinfo + test -f debian/artifacts/test_1_amd64.changes + + extra-repo-keys-files: + needs: [single-package] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: download-keys + run: | + docker run --detach --mount="type=bind,src=${{ github.workspace }},dst=/workspace" --name=download-cont --rm --workdir=/workspace debian:stable-slim tail -f /dev/null + docker exec download-cont apt-get update + docker exec --user="$(id -u):$(id -g)" download-cont apt-get download debian-archive-keyring + docker stop --time=1 download-cont + dpkg-deb --extract debian-archive-keyring_*.deb debian-archive-keyring + { + printf 'debian-archive-keys<>"$GITHUB_OUTPUT" + - uses: ./ + env: + DEB_BUILD_OPTIONS: noautodbgsym + with: + buildpackage-opts: --build=binary --no-sign + docker-image: test/Dockerfile_extra-repo-keys + # An output value instead of an environment variable is used here to + # not interfere with Docker’s environment down the line. + extra-repo-keys: ${{ steps.download-keys.outputs.debian-archive-keys }} + source-dir: test + - run: | + dpkg --info debian/artifacts/test_1_amd64.deb + dpkg --contents debian/artifacts/test_1_amd64.deb | grep ./usr/bin/mybin + test -f debian/artifacts/test_1_amd64.buildinfo + test -f debian/artifacts/test_1_amd64.changes + + extra-repos: + needs: [setup-hook] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: cat test/Makefile_extra-repos >>test/Makefile + - uses: ./ + env: + DEB_BUILD_OPTIONS: noautodbgsym + with: + buildpackage-opts: --build=binary --no-sign + extra-repos: | + # These are intentionally given as two entries: + deb http://deb.debian.org/debian stable contrib + deb http://deb.debian.org/debian stable non-free + setup-hook: | + apt-get update # Called here manually only for testing purposes! + ! apt-cache policy | grep -E ' *release.*[ ,]o=Debian[,$$]' | grep -E '[ ,]c=contrib[,$$]' + ! apt-cache policy | grep -E ' *release.*[ ,]o=Debian[,$$]' | grep -E '[ ,]c=non-free[,$$]' + source-dir: test + - run: | + dpkg --info debian/artifacts/test_1_amd64.deb + dpkg --contents debian/artifacts/test_1_amd64.deb | grep ./usr/bin/mybin + test -f debian/artifacts/test_1_amd64.buildinfo + test -f debian/artifacts/test_1_amd64.changes + + extra-repos-deb822: + needs: [setup-hook] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: cat test/Makefile_extra-repos >>test/Makefile + - uses: ./ + env: + DEB_BUILD_OPTIONS: noautodbgsym + with: + buildpackage-opts: --build=binary --no-sign + extra-repos: | + # These are intentionally given as two entries: + Types: deb + URIs: http://deb.debian.org/debian + Suites: stable + Components: contrib + + Types: deb + URIs: http://deb.debian.org/debian + Suites: stable + Components: non-free + setup-hook: | + apt-get update # Called here manually only for testing purposes! + ! apt-cache policy | grep -E ' *release.*[ ,]o=Debian[,$$]' | grep -E '[ ,]c=contrib[,$$]' + ! apt-cache policy | grep -E ' *release.*[ ,]o=Debian[,$$]' | grep -E '[ ,]c=non-free[,$$]' + source-dir: test + - run: | + dpkg --info debian/artifacts/test_1_amd64.deb + dpkg --contents debian/artifacts/test_1_amd64.deb | grep ./usr/bin/mybin + test -f debian/artifacts/test_1_amd64.buildinfo + test -f debian/artifacts/test_1_amd64.changes + full-build: runs-on: ubuntu-latest steps: diff --git a/README.md b/README.md index 90c7f27..5bf4ab9 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,25 @@ settings are required. Optional and empty by default. +#### `extra-repos` +Extra APT repositories to configure as sources in the build environment. + +Entries can be given in either format supported by APT: one-line style or +deb822 style, see +[`man sources.list`](https://manpages.debian.org/sources.list.5). + +Optional and empty by default. + +#### `extra-repo-keys` +Extra keys for APT to trust in the build environment. Useful in combination +with [`extra-repos`](#extra-repos). + +The parameter can be used to pass either one or multiple ASCII-armored keys, or +a newline-separated list of paths to key files in ASCII-armored or binary +format. Paths to key files must be relative to the workspace. + +Optional and empty by default. + #### `host-arch` The architecture packages are built for. If this parameter is set, cross-compilation is set up with `apt-get` and `dpkg-buildpackage` as described diff --git a/action.yml b/action.yml index af74cf5..ba384ed 100644 --- a/action.yml +++ b/action.yml @@ -26,6 +26,12 @@ inputs: extra-docker-args: description: Additional arguments to 'docker run' when starting the build container required: false + extra-repo-keys: + description: Extra ASCII-armored APT repository keys or paths to keyring files to trust in the build environment + required: false + extra-repos: + description: Extra APT repositories to configure in the build environment (one-line-style or deb822-style format) + required: false host-arch: description: Foreign architecture to setup cross-compilation for required: false @@ -50,6 +56,8 @@ runs: INPUT_DOCKER_IMAGE: ${{ inputs.docker-image }} INPUT_EXTRA_BUILD_DEPS: ${{ inputs.extra-build-deps }} INPUT_EXTRA_DOCKER_ARGS: ${{ inputs.extra-docker-args }} + INPUT_EXTRA_REPO_KEYS: ${{ inputs.extra-repo-keys }} + INPUT_EXTRA_REPOS: ${{ inputs.extra-repos }} INPUT_HOST_ARCH: ${{ inputs.host-arch }} INPUT_SETUP_HOOK: ${{ inputs.setup-hook }} INPUT_SOURCE_DIR: ${{ inputs.source-dir }} diff --git a/scripts/install_build_deps b/scripts/install_build_deps index 3e49aa8..c6f8700 100755 --- a/scripts/install_build_deps +++ b/scripts/install_build_deps @@ -24,6 +24,13 @@ fi # essential packages. It is reasonably safe to blindly assume it is installed. printf "man-db man-db/auto-update boolean false\n" | debconf-set-selections +if printf "%s\n" "$INPUT_EXTRA_REPOS" | grep -q '^deb'; then + extra_repos_ext=.list +else + extra_repos_ext=.sources +fi +printf "%s\n" "$INPUT_EXTRA_REPOS" >"/etc/apt/sources.list.d/build-deb-action${extra_repos_ext}" + apt-get update # shellcheck disable=SC2086 diff --git a/scripts/run b/scripts/run index 5840827..fda7230 100755 --- a/scripts/run +++ b/scripts/run @@ -46,6 +46,8 @@ build_dir=$(mktemp --directory --tmpdir="${RUNNER_TEMP-}" build-deb-action-XXXXX trap clean_up EXIT INT HUP TERM env_file=$build_dir/env +extra_repo_keys_file=$build_dir/build-deb-action.asc +extra_repo_key_files_file=$build_dir/extra_repo_key_files gitconfig_file=$build_dir/gitconfig INPUT_ARTIFACTS_DIR=${INPUT_ARTIFACTS_DIR:-.} @@ -60,6 +62,36 @@ if ! check_path_prefix "$INPUT_SOURCE_DIR" "$GITHUB_WORKSPACE"; then exit 2 fi +touch "$extra_repo_key_files_file" +if [ "$INPUT_EXTRA_REPO_KEYS" ]; then + printf '%s\n' "$INPUT_EXTRA_REPO_KEYS" >"$extra_repo_keys_file" + + while read -r extra_repo_key_file; do + [ "$extra_repo_key_file" ] || continue + + if [ ! -f "$extra_repo_key_file" ]; then + if [ -s "$extra_repo_key_files_file" ]; then + error "extra-repo-keys cannot contain both ASCII-armored keys and key file paths" + exit 2 + fi + + # Looks like (an) ASCII-armored key(s) + break + fi + + if ! check_path_prefix "$extra_repo_key_file" "$GITHUB_WORKSPACE"; then + error "A path to a key file in extra-repo-keys is not in GITHUB_WORKSPACE" + exit 2 + fi + + printf '%s\n' "$extra_repo_key_file" >>"$extra_repo_key_files_file" + done <"$extra_repo_keys_file" + + if [ ! -s "$extra_repo_key_files_file" ]; then + printf '/github/build/build-deb-action.asc\n' >"$extra_repo_key_files_file" + fi +fi + if [ -f "$INPUT_DOCKER_IMAGE" ]; then if ! check_path_prefix "$INPUT_DOCKER_IMAGE" "$GITHUB_WORKSPACE"; then error "docker-image is the path of a Dockerfile but it is not in GITHUB_WORKSPACE" @@ -77,9 +109,12 @@ if [ -f "$INPUT_DOCKER_IMAGE" ]; then fi start_group "Starting build container" -# Docker does not like variable values containing newlines in an --env-file. +# Docker does not like variable values containing newlines in an --env-file, we +# will pass them separately: env \ --unset=INPUT_BEFORE_BUILD_HOOK \ + --unset=INPUT_EXTRA_REPO_KEYS \ + --unset=INPUT_EXTRA_REPOS \ --unset=INPUT_SETUP_HOOK \ >"$env_file" @@ -91,6 +126,7 @@ container_id=$( --env-file="$env_file" \ --env=GITHUB_ACTION_PATH=/github/action \ --env=GITHUB_WORKSPACE=/github/workspace \ + --env=INPUT_EXTRA_REPOS \ --mount="type=bind,src=${GITHUB_ACTION_PATH},dst=/github/action,ro" \ --mount="type=bind,src=${build_dir},dst=/github/build" \ --mount="type=bind,src=${GITHUB_WORKSPACE},dst=/github/workspace" \ @@ -103,6 +139,13 @@ container_id=$( end_group start_group "Setting up build container" +while read -r extra_repo_key_file; do + docker exec "$container_id" install \ + --mode=644 \ + --target-directory=/etc/apt/trusted.gpg.d \ + "$extra_repo_key_file" +done <"$extra_repo_key_files_file" + # git is always available here outside the build container, in the environment # of a run step. diff --git a/test/Dockerfile_extra-repo-keys b/test/Dockerfile_extra-repo-keys new file mode 100644 index 0000000..efac305 --- /dev/null +++ b/test/Dockerfile_extra-repo-keys @@ -0,0 +1,3 @@ +FROM debian:stable-slim + +RUN rm /etc/apt/trusted.gpg.d/debian-archive-*.asc diff --git a/test/Makefile_extra-repos b/test/Makefile_extra-repos new file mode 100644 index 0000000..26e3ce5 --- /dev/null +++ b/test/Makefile_extra-repos @@ -0,0 +1,5 @@ + +.PHONY: test +test: + apt-cache policy | grep -E ' *release.*[ ,]o=Debian[,$$]' | grep -E '[ ,]c=contrib[,$$]' + apt-cache policy | grep -E ' *release.*[ ,]o=Debian[,$$]' | grep -E '[ ,]c=non-free[,$$]'