Skip to content

fix: stacker convert should check if FROMAS base is in current build - #785

Open
jmblatten wants to merge 1 commit into
project-stacker:mainfrom
geico:fix-convert-FROMAS
Open

fix: stacker convert should check if FROMAS base is in current build#785
jmblatten wants to merge 1 commit into
project-stacker:mainfrom
geico:fix-convert-FROMAS

Conversation

@jmblatten

Copy link
Copy Markdown

Currently, stacker converts the base part of a "FROM base AS name"
found in a dockerfile to stacker's from directive with type:docker
and url:docker.
However, the base could be a build stage in the current session.
In that case, stacker's from directive should be type:built and tag:name instead.
This fix cycles thru the build stages to determine which are build stages and which
are bases before converting and sets a flag.

What type of PR is this?
bug

Which issue does this PR fix:
#756

What does this PR do / Why do we need it:
See above.

If an issue # is not available please add repro steps and logs showing the issue:
#756
Steps to reproduce:

myhello.go file contents,

package main

import "fmt"

func main() {
   fmt.Println("hello world!")
}

Dockerfile contents:

FROM golang:1.22 AS mybuild
COPY myhello.go /src/myhello.go
WORKDIR /src
RUN export GOPATH=/go && export PATH=/go/bin:/usr/local/go/bin:$PATH && export HOME=/go && go build -o /bin/myhello ./myhello.go && ls /bin/myhello

FROM alpine AS mybase

FROM mybase AS A
COPY --from=mybuild /bin/myhello /bin/myhello

FROM A AS B
RUN chmod 755 /bin/myhello && \
    /bin/myhello

Resulting, converted stacker.yaml,

A:
  build_env:
    arch: amd64
  from:
    type: docker
    url: docker://mybase
  imports:
  - dest: /bin/myhello
    path: stacker://mybuild/bin/myhello
B:
  build_env:
    arch: amd64
  from:
    type: docker
    url: docker://A
  run:
  - sh -e -c 'chmod 755 /bin/myhello &&     /bin/myhello'
mybase:
  build_env:
    arch: amd64
  from:
    type: docker
    url: docker:alpine
mybuild:
  build_env:
    arch: amd64
  from:
    type: docker
    url: docker:golang:1.22
  imports:
  - dest: /src/myhello.go
    path: myhello.go
  run:
  - mkdir -p /src
  - cd /src
- sh -e -c 'export GOPATH=/go && export PATH=/go/bin:/usr/local/go/bin:$PATH &&
    export HOME=/go && go build -o /bin/myhello myhello.go && ls /bin/myhello'

Note that a stacker build will fail because there isn't a base layer A or B. They are instead stages in a build. Thus they perhaps should be represented as stages in the converted stacker file.

Testing done on this change:

  • CI
  • Manual:
    Same Dockerfile and myhello.go from above.
    stacker with fix, resulting converted stacker.yaml,
A:
  build_env:
    arch: amd64
  from:
    tag: mybase
    type: built
  imports:
  - dest: /bin/myhello
    path: stacker://mybuild/bin/myhello
B:
  build_env:
    arch: amd64
  from:
    tag: A
    type: built
  run:
  - sh -e -c 'chmod 755 /bin/myhello &&     /bin/myhello'
mybase:
  build_env:
    arch: amd64
  from:
    type: docker
    url: docker:alpine
mybuild:
  build_env:
    arch: amd64
  from:
    type: docker
    url: docker:golang:1.22
  imports:
  - dest: /src/myhello.go
    path: myhello.go
  run:
  - mkdir -p /src
  - cd /src
  - sh -e -c 'export GOPATH=/go && export PATH=/go/bin:/usr/local/go/bin:$PATH &&
    export HOME=/go && go build -o /bin/myhello myhello.go && ls /bin/myhello'

Note that A and B are tagged while mybuild and mybase pull in base images. stacker build should work.

Automation added to e2e:
None

Will this break upgrades or downgrades?
No

Does this PR introduce any user-facing change?:
No, because previously the converted file would not build.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

    Currently, stacker converts the base part of a "FROM base AS name"
    found in a dockerfile to stacker's from directive with type:docker
    and url:docker.
    However, the base could be a build stage in the current session.
    In that case, stacker's from directive should be type:built and
    tag:<something> instead.

Signed-off-by: Joy Latten <joylatten@geico.com>
@hallyn

hallyn commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Could you pretty easily add the testcase from your description as a new bats test?

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.86%. Comparing base (2dc1b06) to head (c4a9564).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/stacker/convert.go 50.00% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #785       +/-   ##
===========================================
+ Coverage   12.42%   54.86%   +42.43%     
===========================================
  Files          55       55               
  Lines        5909     5924       +15     
===========================================
+ Hits          734     3250     +2516     
+ Misses       5055     2102     -2953     
- Partials      120      572      +452     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@jmblatten

Copy link
Copy Markdown
Author

Looking into adding testcase(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants