Skip to content

Conversation

@jjbustamante
Copy link
Member

@jjbustamante jjbustamante commented Jan 26, 2025

Summary

This PR is intended to be an initial implementation of the Execution Environment RFC. it uses an initial implementation on lifecycle developed by @jabrown85 in the following branch

The RFC is in a voting state; we must include those changes in some API version and the current code should be updated afterward.

Changes added

  • New flag to pack build command was added, --exec-env, to pass through the execution environment during the build process. By default, the value will be production

Output

Before

The Execution Environment feature doesn't exist, nothing to show here.

After

I added a bunch of unit tests to the updated toml files, but to test all together I used our sample repo. The hello-moon buildpack prints some environment variables during its execution.

Using a current lifecycle.
  • I compiled pack with the changes made in this PR
  • I built our sample ruby application, using our sample builder available in docker hub, using the new --exec-env flag

Notice in the following log how pack is sending the CNB_EXEC_ENV environment variable with the value we set in the --exec-env flag to the lifecycle

~/go/src/github.com/buildpacks/pack/out/pack build my-sample-ruby-app:no-exec-env --builder cnbs/sample-builder:alpine --path ./ruby-bundler/ -v --trust-builder --exec-env test

Running the creator on OS linux from image index.docker.io/cnbs/sample-builder:alpine with:
Container Settings:
  Args: /cnb/lifecycle/creator -daemon -launch-cache /launch-cache -log-level debug -app /workspace -cache-dir /cache -run-image cnbs/sample-base-run:alpine my-sample-ruby-app:no-exec-env
  System Envs: CNB_PLATFORM_API=0.13 CNB_EXEC_ENV=test
  Image: index.docker.io/cnbs/sample-builder:alpine
  User: root
  Labels: map[author:pack]

Also notice, because this lifecycle version doesn't know anything about the CNB_EXEC_ENV when our hello-moon buildpacks runs, we don't see the environment variable there.

===> ANALYZING
===> DETECTING
Timer: Detector started at 2025-02-03T12:38:09Z
======== Results ========
..
Timer: Restorer ran for 411.809µs and ended at 2025-02-03T12:38:09Z
===> BUILDING
Timer: Builder started at 2025-02-03T12:38:09Z
Running build for buildpack samples/[email protected]
Looking up buildpack
Finding plan
Creating plan directory
Preparing paths
Running build command
---> Hello World buildpack
     platform_dir files:
       /platform:
     env_dir: /platform/env
     env vars:
       declare -x CNB_BP_PLAN_PATH="/tmp/samples_hello-world-1025312133/samples_hello-world/plan.toml"
       declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-world/0.0.1"
       declare -x CNB_LAYERS_DIR="/layers/samples_hello-world"
       declare -x CNB_PLATFORM_DIR="/platform"
       declare -x CNB_STACK_ID="io.buildpacks.samples.stacks.alpine"
       declare -x CNB_TARGET_ARCH="amd64"
       declare -x CNB_TARGET_DISTRO_NAME="alpine"
       declare -x CNB_TARGET_DISTRO_VERSION="3.18.3"
       declare -x CNB_TARGET_OS="linux"
       declare -x HOME="/home/cnb"
       declare -x HOSTNAME="9dd21023870a"
       declare -x OLDPWD
       declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
       declare -x PWD="/workspace"
       declare -x SHLVL="1"
     layers_dir: /layers/samples_hello-world
     plan_path: /tmp/samples_hello-world-1025312133/samples_hello-world/plan.toml
     plan contents:
       [[entries]]
         name = "some-world"
       
       [[entries]]
         name = "some-world"
         [entries.metadata]
           world = "Earth-616"

---> Done
Processing layers
Running build command
---> Hello Moon buildpack
     env_dir: /platform/env
     env vars:
       declare -x CNB_BP_PLAN_PATH="/tmp/samples_hello-moon-3157340986/samples_hello-moon/plan.toml"
       declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-moon/0.0.1"
       declare -x CNB_LAYERS_DIR="/layers/samples_hello-moon"
       declare -x CNB_PLATFORM_DIR="/platform"
       declare -x CNB_STACK_ID="io.buildpacks.samples.stacks.alpine"
       declare -x CNB_TARGET_ARCH="amd64"
       declare -x CNB_TARGET_DISTRO_NAME="alpine"
       declare -x CNB_TARGET_DISTRO_VERSION="3.18.3"
       declare -x CNB_TARGET_OS="linux"
       declare -x HOME="/home/cnb"
       declare -x HOSTNAME="9dd21023870a"
       declare -x OLDPWD
       declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
       declare -x PWD="/workspace"
       declare -x SHLVL="1"
     layers_dir: /layers/samples_hello-moon
     plan_path: /tmp/samples_hello-moon-3157340986/samples_hello-moon/plan.toml
     plan contents:

---> Done
... 
Timer: Builder ran for 6.917745ms and ended at 2025-02-03T12:38:09Z
===> EXPORTING
Successfully built image my-sample-ruby-app:no-exec-env
Using a lifecycle compiled from Jesse's branch

As I mentioned before, @jabrown85 created a lifecycle implementation for this RFC, I compiled a lifecycle from that branch and created a sample builder with it. I built the sample ruby application using that builder.

Similar to our previous example, pack sends the CNB_EXEC_ENV with the value we specified in the command line.

> ~/go/src/github.com/buildpacks/pack/out/pack  build sample-ruby-app:with-exec-env --builder my-exec-env-builder:alpine --path ./ruby-bundler/ -v --trust-builder --exec-env test

ning the creator on OS linux from image index.docker.io/library/my-exec-env-builder:alpine with:
Container Settings:
  Args: /cnb/lifecycle/creator -daemon -launch-cache /launch-cache -log-level debug -app /workspace -cache-dir /cache -run-image cnbs/sample-base-run:alpine sample-ruby-app:with-exec-env
  System Envs: CNB_PLATFORM_API=0.13 CNB_EXEC_ENV=test
  Image: index.docker.io/library/my-exec-env-builder:alpine
  User: root
  Labels: map[author:pack]

Now, we can see the environment variable CNB_EXEC_ENV is available to the buildpack at execution time to the build/detect binaries.

===> BUILDING
Timer: Builder started at 2025-02-03T12:39:11Z
     env vars:
               declare -x CNB_BP_PLAN_PATH="/tmp/samples_hello-world-3047059202/samples_hello-world/plan.toml"
               declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-world/0.0.1"
       declare -x CNB_EXEC_ENV="test"
               declare -x CNB_LAYERS_DIR="/layers/samples_hello-world"
               declare -x CNB_PLATFORM_DIR="/platform"
               declare -x CNB_STACK_ID="io.buildpacks.samples.stacks.alpine"
               declare -x CNB_TARGET_ARCH="amd64"
               declare -x CNB_TARGET_DISTRO_NAME="alpine"
               declare -x CNB_TARGET_DISTRO_VERSION="3.18.3"
               declare -x CNB_TARGET_OS="linux"

Documentation

  • Should this change be documented?
    • Yes, see #___
    • No

Related

Resolves #___

@github-actions github-actions bot added this to the 0.37.0 milestone Jan 26, 2025
@github-actions github-actions bot added the type/enhancement Issue that requests a new feature or improvement. label Jan 26, 2025
@jjbustamante jjbustamante changed the title WIP - adding flag to set the CNB_EXEC_ENV Proof of Concept for Execution Environment RFC Jan 26, 2025
@codecov
Copy link

codecov bot commented Jan 26, 2025

Codecov Report

❌ Patch coverage is 14.92537% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.64%. Comparing base (d1a30b6) to head (0285c59).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2324      +/-   ##
==========================================
- Coverage   60.76%   60.64%   -0.12%     
==========================================
  Files         254      255       +1     
  Lines       19165    19228      +63     
==========================================
+ Hits        11643    11658      +15     
- Misses       6712     6759      +47     
- Partials      810      811       +1     
Flag Coverage Δ
os_linux 60.28% <14.93%> (-0.12%) ⬇️
os_macos-arm64 58.06% <14.93%> (-0.11%) ⬇️
os_windows 60.14% <14.93%> (-0.11%) ⬇️
unit 60.64% <14.93%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions bot added this to the 0.37.0 milestone Mar 5, 2025
@jjbustamante jjbustamante modified the milestones: 0.37.0, 0.38.0 Mar 14, 2025
@edmorley
Copy link
Contributor

For anyone else following along with this work - there is now a tracking issue for implementing the RFC at:
buildpacks/rfcs#327

Resolved conflicts by keeping both features:
- ExecutionEnv/CNBExecutionEnv from execution-environment-poc branch
- InsecureRegistries from main branch

Files with resolved conflicts:
- internal/commands/build.go
- internal/commands/build_test.go
- pkg/client/build.go
  Changes Made:

  1. internal/build/lifecycle_executor.go (2 lines added)
    - Added Platform API versions 0.14 and 0.15 to SupportedPlatformAPIVersions
    - This allows pack to support the new execution environment feature which requires Platform API 0.15
  2. internal/build/phase_config_provider.go (1 line changed)
    - Updated the Platform API version check from 0.13 to 0.15 for the CNB_EXEC_ENV environment variable
  3. internal/build/fakes/fake_builder.go (7 lines added)
    - Added WithExecutionEnvironment() helper function for tests
    - Allows tests to easily set the execution environment in lifecycle options
  4. internal/build/phase_config_provider_test.go (41 lines added)
    - Added comprehensive tests for the execution environment feature:
        - ✅ Test that CNB_EXEC_ENV is set when Platform API >= 0.15
      - ✅ Test that CNB_EXEC_ENV is NOT set when Platform API < 0.15
    - Added import for "github.com/buildpacks/lifecycle/api" package

  Existing Test Coverage (Already in PR):

  1. internal/commands/build_test.go
    - ✅ Tests that default exec-env is 'production'
    - ✅ Tests with valid characters (letters, numbers, dots, hyphens)
    - ✅ Tests with invalid characters (shows proper error)
    - ✅ Comprehensive validation tests for exec-env flag
  2. builder/config_reader_test.go
    - ✅ Tests reading exec-env from builder configuration
  3. pkg/project/project_test.go
    - ✅ Tests reading exec-env from project.toml (schema v0.3)
    - ✅ Tests for buildpack groups, pre-groups, and post-groups

  Test Results:

  - All phase config provider tests: PASSING ✅
  - All build command tests: PASSING ✅
  - Coverage for exec-env flag validation: COMPLETE ✅
  - Coverage for CNB_EXEC_ENV environment variable: COMPLETE ✅
  - Coverage for Platform API version gating: COMPLETE ✅

  The test coverage for your ExecutionEnvironment feature is now comprehensive and covers:
  - Command-line flag validation
  - Environment variable setting based on Platform API version
  - Builder and project configuration reading
  - Edge cases and error conditions

Signed-off-by: Juan Bustamante <[email protected]>
@jjbustamante
Copy link
Member Author

spect PRs:

  • 415
  • 416
    were already merged, also once Lifecycle PR 1539 is merged, We will be able to merge and release this feature!

@github-actions github-actions bot added the type/chore Issue that requests non-user facing changes. label Nov 23, 2025
@jjbustamante jjbustamante modified the milestones: 0.39.0, 0.40.0 Nov 23, 2025
@edmorley
Copy link
Contributor

edmorley commented Jan 8, 2026

@jjbustamante Hi! Now that buildpacks/lifecycle#1539 is merged/released, are we ready to proceed with the changes on the Pack CLI side? :-)

@jjbustamante
Copy link
Member Author

@jjbustamante Hi! Now that buildpacks/lifecycle#1539 is merged/released, are we ready to proceed with the changes on the Pack CLI side? :-)

Hi @edmorley! Yes, I am gonna work on merging these changes and releasing 0.40.0

@edmorley
Copy link
Contributor

Cross-linking the tracking issue for this:
#2403

@jjbustamante
Copy link
Member Author

@jjbustamante Hi! Now that buildpacks/lifecycle#1539 is merged/released, are we ready to proceed with the changes on the Pack CLI side? :-)

Hi @edmorley! Yes, I am gonna work on merging these changes and releasing 0.40.0

@edmorley just a quick update: I had to work on migrating docker library to moby to be able to update to lifecycle 0.21.0. I just merged PR #2512 and now I will try to get this one to the last line

@github-actions github-actions bot removed the type/chore Issue that requests non-user facing changes. label Jan 20, 2026
Add missing import for github.com/buildpacks/lifecycle/api package
required by execution environment tests that use api.MustParse().

The tests added in this branch for CNB_EXEC_ENV functionality
reference api.Version and api.MustParse() but the import was missing,
causing compilation errors after merging latest changes from main.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: Juan Bustamante <[email protected]>
@jjbustamante jjbustamante force-pushed the jjbustamante/execution-environment-poc branch from 21acb9f to fdcd0b4 Compare January 20, 2026 12:50
@jjbustamante jjbustamante marked this pull request as ready for review January 20, 2026 12:51
@jjbustamante jjbustamante requested review from a team as code owners January 20, 2026 12:51
@jjbustamante jjbustamante changed the title Proof of Concept for Execution Environment RFC Execution Environment RFC Implementation Jan 20, 2026
@jjbustamante
Copy link
Member Author

I am going to test the branch again before merging with the steps I mentioned above, if everything is fine, I will merge the PR

@jjbustamante
Copy link
Member Author

✅ Verified with Lifecycle 0.21.0 and Platform API 0.15

I've successfully tested this PR with the official lifecycle 0.21.0 release, which includes Platform API 0.15 support and the Execution Environment feature.

Test Setup

  • Pack: Built from this PR branch (jjbustamante/execution-environment-poc)
  • Lifecycle: buildpacksio/lifecycle:0.21.0 (Platform API 0.15)
  • Buildpacks: Updated sample buildpacks to use Buildpack API 0.12 (required for CNB_EXEC_ENV support)
  • Builder: Custom builder with lifecycle 0.21.0

Test Command

~/go/src/github.com/buildpacks/pack/out/pack build my-sample-ruby-app:with-exec-env \
  --builder my-exec-env-builder:alpine \
  --path ./ruby-bundler/ \
  -v \
  --exec-env test

Results

✅ Pack correctly passes CNB_EXEC_ENV to lifecycle

All lifecycle phases show the environment variable in System Envs:

System Envs: 'CNB_PLATFORM_API=0.15 CNB_EXEC_ENV=test'

✅ Buildpacks receive CNB_EXEC_ENV

hello-world buildpack:

[builder] ---> Hello World buildpack
[builder]      env vars:
[builder]        declare -x CNB_EXEC_ENV="test"
[builder]        declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-world/0.0.1"
[builder]        declare -x CNB_LAYERS_DIR="/layers/samples_hello-world"
[builder]        declare -x CNB_PLATFORM_DIR="/platform"
...

hello-moon buildpack:

[builder] ---> Hello Moon buildpack
[builder]      env vars:
[builder]        declare -x CNB_EXEC_ENV="test"
[builder]        declare -x CNB_BUILDPACK_DIR="/cnb/buildpacks/samples_hello-moon/0.0.1"
[builder]        declare -x CNB_LAYERS_DIR="/layers/samples_hello-moon"
...

Key Findings

  1. Pack implementation is correct - The --exec-env flag and CNB_EXEC_ENV environment variable are being properly passed to the lifecycle
  2. Platform API 0.15 support works - The conditional logic using lifecycleExec.platformAPI.AtLeast("0.15") correctly enables the feature
  3. Buildpack API 0.12+ required - Buildpacks must use Buildpack API >= 0.12 to receive CNB_EXEC_ENV (as per the spec)

Notes

  • The lifecycle 0.21.0 release includes both Platform API 0.15 support and Exec-Env support (release notes)
  • The execution environment feature was introduced in Buildpack API 0.12
  • The platform-level specification is defined in Platform API 0.15

The PR is ready for review! 🚀

@jjbustamante jjbustamante merged commit 94348a5 into main Jan 23, 2026
15 checks passed
@jjbustamante jjbustamante deleted the jjbustamante/execution-environment-poc branch January 23, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/enhancement Issue that requests a new feature or improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants