From d4a266a43199b56db3ee74fa90e9909b78f04256 Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 21 Sep 2024 16:28:42 +0000 Subject: [PATCH 1/5] .devcontainer: Added Implement a dev container to make contributing easier, adding docker-in-docker for building images locally, and nektos/act for testing GH actions locally. --- .devcontainer/Dockerfile | 6 ++++++ .devcontainer/devcontainer.json | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..e562dd43 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,6 @@ +ARG VARIANT=5-bookworm +FROM perl:${VARIANT} + +COPY cpanfile /tmp/cpanfile +RUN cpm install -g --with-develop --cpanfile /tmp/cpanfile \ + && rm -rf /root/.perl-cpm /tmp/cpanfile diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..13e06f45 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,31 @@ +{ + "build": { + "dockerfile": "./Dockerfile", + "context": ".." + }, + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "configureZshAsDefaultShell": "true" + }, + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/dhoeric/features/act:1": {} + }, + "customizations": { + "vscode": { + "settings": { + "files.associations": { + "cpanfile": "cpanfile" + } + }, + "extensions": [ + "bscan.perlnavigator", + "bayashi.perlcpanfile", + "stkb.rewrap", + "GitHub.vscode-pull-request-github", + "GitHub.vscode-github-actions" + ] + } + }, + "remoteUser": "vscode" +} From 5c36c52367c4c4f79de1da9dd61a750045c42191 Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 21 Sep 2024 16:34:52 +0000 Subject: [PATCH 2/5] generate.pl: allow setting alternate dir for downloads This can be helpful in docker volumes or dev containers, where using the default location under the repo root can have issues due to host/container sync. --- generate.pl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/generate.pl b/generate.pl index 36367de9..5b3a87ad 100755 --- a/generate.pl +++ b/generate.pl @@ -122,8 +122,9 @@ sub die_with_sample { die_with_sample unless defined $config->{releases}; die_with_sample unless ref $config->{releases} eq "ARRAY"; -if (!-d "downloads") { - mkdir "downloads" or die "Couldn't create a downloads directory"; +my $downloads = $ENV{DOCKER_PERL_DOWNLOADS_DIR} // "downloads"; +if (!-d "$downloads") { + mkdir "$downloads" or die "Couldn't create a downloads directory at $downloads"; } for my $build (@{$config->{builds}}) { @@ -141,21 +142,21 @@ sub die_with_sample { my $tarball = CPAN::Perl::Releases::MetaCPAN::perl_tarballs($release->{version})->{'tar.gz'}; my ($file) = File::Basename::fileparse($tarball); my $url = "https://cpan.metacpan.org/authors/id/$tarball"; - if (-f "downloads/$file" && `sha256sum downloads/$file` =~ /^\Q$release->{sha256}\E\s+\Qdownloads\/$file\E/) { + if (-f "$downloads/$file" && `sha256sum $downloads/$file` =~ /^\Q$release->{sha256}\E\s+\Q$downloads\/$file\E/) { print "Skipping download of $file, already current\n"; } else { print "Downloading $url\n"; - getstore($url, "downloads/$file"); + getstore($url, "$downloads/$file"); } { - my $dir = "downloads/perl-$release->{version}"; + my $dir = "$downloads/perl-$release->{version}"; qx{rm -fR $dir}; mkdir $dir or die "Couldn't create $dir"; qx{ - tar -C "downloads" -xf $dir.tar.gz &&\ + tar -C "$downloads" -xf $dir.tar.gz &&\ cd $dir &&\ - find . -exec chmod u+w {} + &&\ + chown -R \$(id -u):\$(id -g) . &&\ git init &&\ git add . &&\ git commit -m tmp From d837a713f5cc937619a49ec23d805c16be1b9852 Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 21 Sep 2024 16:44:41 +0000 Subject: [PATCH 3/5] .devcontainer: set alternate downloads dir --- .devcontainer/devcontainer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 13e06f45..26defd2f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,6 +3,9 @@ "dockerfile": "./Dockerfile", "context": ".." }, + "containerEnv": { + "DOCKER_PERL_DOWNLOADS_DIR": "/tmp/docker-perl-downloads" + }, "features": { "ghcr.io/devcontainers/features/common-utils:2": { "configureZshAsDefaultShell": "true" From 2fca851eb98f3f393ed114cb365f42adcb4d4aaa Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 21 Sep 2024 17:42:02 +0000 Subject: [PATCH 4/5] workflows: improve generate dockerfile workflow - Run under perl:devel container - Run only for changes on selected paths - Install prereqs via cpm - Fail when extra diffs are detected --- .../generate-dockerfiles-patches.yml | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/.github/workflows/generate-dockerfiles-patches.yml b/.github/workflows/generate-dockerfiles-patches.yml index 7f11cfa7..7dd95583 100644 --- a/.github/workflows/generate-dockerfiles-patches.yml +++ b/.github/workflows/generate-dockerfiles-patches.yml @@ -3,32 +3,54 @@ name: Generate Dockerfiles/patches on: push: branches: - - '**' + - master tags-ignore: - '*' pull_request: + paths: + - cpanfile + - config.yml + - generate.pl + - .github/workflows/generate-dockerfiles-patches.yml jobs: generate: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Set up git user name and email run: | git config --global user.email "test@github-actions" git config --global user.name "GitHub Actions" - - uses: actions/checkout@master + - name: Install system perl and cpanm run: | - sudo apt-get install --no-install-recommends -y perl cpanminus + sudo apt-get update && sudo apt-get install -y --no-install-recommends perl cpanminus + - name: Install dependencies run: | - cpanm --quiet --installdeps --notest -L local . + sudo cpanm --quiet --installdeps --notest . + - name: Generate Dockerfiles/patches + id: generate run: | - perl -Ilocal/lib/perl5 ./generate.pl - - name: Show diffstat (if any) - run: | - git --no-pager diff --stat HEAD - - name: Show diffstat (if any) + export DOCKER_PERL_DOWNLOADS_DIR=/tmp/docker-perl-downloads + perl ./generate.pl + /usr/bin/git --no-pager diff --stat > diffstat.txt + if [[ -s diffstat.txt ]]; then + echo has_extra_diffs=1 >> $GITHUB_OUTPUT + fi + + - name: Fail if there are extra diffs + if: steps.generate.outputs.has_extra_diffs run: | - git --no-pager diff --stat HEAD + echo "::error title=generate::Extra diffs found during generate" + echo "Additional changes found during generate - check diffstat below:" + echo "::group::diffstat" + cat diffstat.txt + echo "::endgroup::" + echo + + exit 1 From 558775c49a6e79914253c10a7b962b34bf4113d7 Mon Sep 17 00:00:00 2001 From: "Zak B. Elep" Date: Sat, 21 Sep 2024 20:07:21 +0000 Subject: [PATCH 5/5] workflows: build image only on build context changes Also switch to using docker-buildx, and remove unneeded step. --- .github/workflows/build-image.yml | 37 ++++++++++++++++--------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index b2eb606d..affa84b0 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -1,12 +1,11 @@ name: Build and Test on: - push: - branches: - - '**' - tags-ignore: - - '*' pull_request: + paths: + - '**/Dockerfile' + - '!.devcontainer/Dockerfile' + - '**/DevelPatchPerl.patch' defaults: run: @@ -18,46 +17,56 @@ jobs: runs-on: ubuntu-latest outputs: matrix: ${{ steps.generate.outputs.matrix }} + steps: - - uses: actions/checkout@master + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - id: generate name: Enumerate Dockerfiles run: | matrix="$(dirname */Dockerfile | sort -rn | jq -csR 'rtrimstr("\n") | split("\n") | { directory: . }')" echo "matrix=$matrix" >> $GITHUB_OUTPUT + build-image: needs: generate-matrix runs-on: ubuntu-latest strategy: matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} name: ${{ matrix.directory }} + steps: - - uses: actions/checkout@master + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Clone docker-library/official-images (for testing) run: | git clone --depth 1 --single-branch https://github.com/docker-library/official-images.git + - name: Build image run: | docker version dir='${{ matrix.directory }}' img="perl:${dir//,/-}" - docker build -t "$img" "$dir" + docker buildx build --progress=plain -t "$img" "$dir" + - name: Inspect image creation and tag time run: | dir='${{ matrix.directory }}' img="perl:${dir//,/-}" docker image inspect --format '{{.Created}}' "$img" docker image inspect --format '{{.Metadata.LastTagTime}}' "$img" + - name: Run tests from docker-library/official-images run: | dir='${{ matrix.directory }}' img="perl:${dir//,/-}" ./official-images/test/run.sh "$img" + - name: Run HTTPS access test run: | dir='${{ matrix.directory }}' img="perl:${dir//,/-}" docker run "$img" perl -MHTTP::Tiny -E 'if (HTTP::Tiny->new->get("https://github.com")->{status} == 200) { exit 0 } exit 1' + - name: Run cpanm install test run: | dir='${{ matrix.directory }}' @@ -67,6 +76,7 @@ jobs: docker run "$img" cpanm -v Net::DNS@1.45_02 fi docker run "$img" cpanm -v Mojolicious + - name: Run cpanm no-lwp by default test run: | dir='${{ matrix.directory }}' @@ -74,6 +84,7 @@ jobs: if [[ "$dir" != *"slim"* ]]; then docker run "$img" bash -c "cpanm -v -n LWP && cpanm -v -n local::lib" fi + - name: Run cpm install test run: | dir='${{ matrix.directory }}' @@ -83,13 +94,3 @@ jobs: docker run "$img" cpm install -v Net::DNS@1.45_02 fi docker run "$img" cpm install -v Mojolicious - - name: COPY all to default WORKDIR - run: | - dir='${{ matrix.directory }}' - img="perl:${dir//,/-}" - mkdir -p test/lib - cat <Dockerfile - FROM $img - COPY . . - EOF - docker build -f Dockerfile test