From e3c208729a8f8520e2f59e1c43fa3453369c3c21 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:23:40 +0100 Subject: [PATCH] Improve tutorial rundoc determinism To try and prevent PRs being opened every week even if nothing has actually changed. Specifically: - Uses `--pull-policy if-not-present` to avoid the builder image SHA from ended up in the logs. - Replaces timestamps, bundler output, image digests etc in the `pack build` output - Uses a fake image digest in the `docker image ls` output --- docs/src/ruby/multiple_langs.md | 8 +++++--- docs/src/ruby/what_is_pack_build.md | 2 +- docs/src/shared/pack_build.md | 7 ++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/src/ruby/multiple_langs.md b/docs/src/ruby/multiple_langs.md index 0a0db30..4c1d23a 100644 --- a/docs/src/ruby/multiple_langs.md +++ b/docs/src/ruby/multiple_langs.md @@ -4,7 +4,7 @@ Language support is provided by individual buildpacks that are shipped with the In addition to this auto-detection behavior, you can specify buildpacks through the `--buildpack` flag with the `pack` CLI or through a [project.toml](https://buildpacks.io/docs/for-app-developers/how-to/build-inputs/specify-buildpacks/) file at the root of your application. -For example, if you wanted to install both Ruby, NodeJS and Python you could create a `project.toml` file in the root of your application and specify those buildpacks. +For example, if you wanted to install both Ruby, Node.js and Python you could create a `project.toml` file in the root of your application and specify those buildpacks. ```toml :::>> file.write project.toml @@ -30,8 +30,10 @@ uri = "heroku/procfile" Ensure that a `requirements.txt` file, a `package.json` file and a `Gemfile.lock` file all exist and then build your application: ``` -:::>> $ touch requirements.txt -:::>> $ pack build my-image-name --path . +$ pack build my-image-name --path . +:::-- $ touch requirements.txt +:::-- $ docker rmi -f my-image-name +:::-> $ pack build my-image-name --path . --pull-policy if-not-present --clear-cache | sed --regexp-extended -e '/Fetching gem metadata/,/Bundle complete/d' -e "/$(date --iso)/d" -e 's/Done \(.+s\)/Done/' -e 's/\.\.\.+ \(.+s\)/.../' -e 's/\b[0-9a-f]{12}\b/abcdef012345/' ``` You can run the image and inspect everything is installed as expected: diff --git a/docs/src/ruby/what_is_pack_build.md b/docs/src/ruby/what_is_pack_build.md index 56634ba..5ec4008 100644 --- a/docs/src/ruby/what_is_pack_build.md +++ b/docs/src/ruby/what_is_pack_build.md @@ -13,7 +13,7 @@ When you run `pack build` with a builder, each buildpack runs a detection script After the detect phase, each buildpack will execute. Buildpacks can inspect your project, install files to disk, run commands, write environment variables, [and more](https://buildpacks.io/docs/for-buildpack-authors/). You can see some examples of that in the output above. For example, the Ruby buildpack installs dependencies from the `Gemfile` automatically: ``` -:::-> $ grep "bundle install" -m1 -A10 ./build_output.txt +:::-> $ grep "bundle install" -m1 ./build_output.txt ``` If you’re familiar with Dockerfile you might know that [many commands in a Dockerfile will create a layer](https://dockerlabs.collabnix.com/beginners/dockerfile/Layering-Dockerfile.html). Buildpacks also use layers, but the CNB buildpack API provides for fine grained control over what exactly is in these layers and how they’re composed. Unlike Dockerfile, all images produced by CNBs [can be rebased](https://tag-env-sustainability.cncf.io/blog/2023-12-reduce-reuse-rebase-buildpacks/#reduce-reuserebase). The CNB api also improves on many of the pitfalls outlined in the satirical article [Write a Good Dockerfile in 19 'Easy' Steps](https://jkutner.github.io/2021/04/26/write-good-dockerfile.html). diff --git a/docs/src/shared/pack_build.md b/docs/src/shared/pack_build.md index 6f72f62..df21846 100644 --- a/docs/src/shared/pack_build.md +++ b/docs/src/shared/pack_build.md @@ -6,8 +6,8 @@ Now build an image named `my-image-name` by executing the heroku builder against ``` $ pack build my-image-name --path . :::-- $ docker rmi -f my-image-name -:::-- $ pack build my-image-name --path . 2>&1 | tee build_output.txt -:::-> $ cat build_output.txt +:::-- $ pack build my-image-name --path . --pull-policy if-not-present --clear-cache 2>&1 | tee build_output.txt +:::-> $ cat build_output.txt | sed --regexp-extended -e '/Fetching gem metadata/,/Bundle complete/d' -e "/$(date --iso)/d" -e 's/Done \(.+s\)/Done/' -e 's/\.\.\.+ \(.+s\)/.../' -e 's/\b[0-9a-f]{12}\b/abcdef012345/' ``` > [!NOTE] @@ -16,5 +16,6 @@ $ pack build my-image-name --path . Verify that you see “Successfully built image my-image-name” at the end of the output. And verify that the image is present locally: ``` -:::>> $ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}" | grep my-image-name +$ docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}" | grep my-image-name +:::-> $ docker image ls --format "table abcdef012345\t{{.Repository}}\t{{.Tag}}" | grep my-image-name ```