Skip to content

Commit 398c8cd

Browse files
authored
Merge branch 'main' into enhancement/jjbustamante/flatten-1880/part-1
2 parents 9fbc649 + b12c9b3 commit 398c8cd

42 files changed

Lines changed: 1334 additions & 144 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ updates:
44
- package-ecosystem: "gomod"
55
directory: "/"
66
schedule:
7-
# Check for updates to GitHub Actions every weekday
8-
interval: "daily"
7+
interval: "weekly"
8+
groups:
9+
# Group all minor/patch go dependencies into a single PR.
10+
go-dependencies:
11+
update-types:
12+
- "minor"
13+
- "patch"
914
labels:
1015
- "dependencies"
1116
- "go"
@@ -15,8 +20,7 @@ updates:
1520
- package-ecosystem: "github-actions"
1621
directory: "/"
1722
schedule:
18-
# Check for updates to GitHub Actions every weekday
19-
interval: "daily"
23+
interval: "weekly"
2024
labels:
2125
- "dependencies"
2226
- "github_actions"

.github/workflows/delivery-docker.yml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,21 @@ on:
1616
default: false
1717

1818
env:
19-
BUILDER: "paketobuildpacks/builder-jammy-tiny"
2019
IMG_NAME: 'pack'
2120
USERNAME: 'buildpacksio'
2221

2322
jobs:
2423
deliver-docker:
24+
strategy:
25+
matrix:
26+
config: [tiny, base]
27+
include:
28+
- config: tiny
29+
base_image: gcr.io/distroless/static
30+
suffix:
31+
- config: base
32+
base_image: ubuntu:jammy
33+
suffix: -base
2534
runs-on: ubuntu-latest
2635
steps:
2736
- name: Determine version
@@ -42,16 +51,6 @@ jobs:
4251
uses: actions/checkout@v4
4352
with:
4453
ref: v${{ steps.version.outputs.result }}
45-
# This has to come after the first checkout, so it isn't clobbered
46-
- name: Checkout delivery configuration
47-
uses: actions/checkout@v4
48-
with:
49-
path: ./head
50-
- name: Setup Working Dir
51-
shell: bash
52-
run: |
53-
rm project.toml || true
54-
cp head/.github/workflows/delivery/docker/project.toml project.toml
5554
- name: Determine App Name
5655
run: 'echo "IMG_NAME=${{ env.USERNAME }}/${{ env.IMG_NAME }}" >> $GITHUB_ENV'
5756
- name: Login to Dockerhub
@@ -61,16 +60,21 @@ jobs:
6160
password: ${{ secrets.DOCKER_PASSWORD }}
6261
- uses: docker/setup-qemu-action@v3
6362
- uses: docker/setup-buildx-action@v3
64-
- uses: buildpacks/github-actions/setup-tools@v5.4.0
63+
- uses: buildpacks/github-actions/setup-tools@v5.5.0
6564
- name: Buildx Build/Publish
6665
run: |
6766
docker buildx build . \
68-
--tag ${{ env.IMG_NAME }}:${{ steps.version.outputs.result }} \
67+
--tag ${{ env.IMG_NAME }}:${{ steps.version.outputs.result }}${{ matrix.suffix }} \
6968
--platform linux/amd64,linux/arm64 \
7069
--build-arg pack_version=${{ steps.version.outputs.result }} \
70+
--build-arg base_image=${{ matrix.base_image }} \
7171
--provenance=false \
7272
--push
73+
- name: Tag Image as Base
74+
if: ${{ (github.event.release != '' || github.event.inputs.tag_latest) && matrix.config == 'base' }}
75+
run: |
76+
crane copy ${{ env.IMG_NAME }}:${{ steps.version.outputs.result }} ${{ env.IMG_NAME }}:base
7377
- name: Tag Image as Latest
74-
if: ${{ github.event.release != '' || github.event.inputs.tag_latest }}
78+
if: ${{ (github.event.release != '' || github.event.inputs.tag_latest) && matrix.config != 'base' }}
7579
run: |
7680
crane copy ${{ env.IMG_NAME }}:${{ steps.version.outputs.result }} ${{ env.IMG_NAME }}:latest

.github/workflows/delivery/docker/project.toml

Lines changed: 0 additions & 7 deletions
This file was deleted.

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
ARG base_image=gcr.io/distroless/static
2+
13
FROM golang:1.20 as builder
24
ARG pack_version
35
ENV PACK_VERSION=$pack_version
46
WORKDIR /app
57
COPY . .
68
RUN make build
79

8-
FROM scratch
10+
FROM ${base_image}
911
COPY --from=builder /app/out/pack /usr/local/bin/pack
10-
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
11-
COPY --from=builder /tmp /tmp
1212
ENTRYPOINT [ "/usr/local/bin/pack" ]

acceptance/assertions/output.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ func (o OutputAssertionManager) IncludesPrefixedGoogleBuilder() {
182182
}
183183

184184
var herokuBuilders = []string{
185+
"heroku/builder:20",
185186
"heroku/builder:22",
186-
"heroku/buildpacks:20",
187187
}
188188

189189
func (o OutputAssertionManager) IncludesHerokuBuilders() {

acceptance/testdata/pack_fixtures/report_output.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Pack:
22
Version: {{ .Version }}
33
OS/Arch: {{ .OS }}/{{ .Arch }}
44

5-
Default Lifecycle Version: 0.17.1
5+
Default Lifecycle Version: 0.17.2
66

77
Supported Platform APIs: 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 0.11, 0.12
88

builder/config_reader.go

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66
"path/filepath"
7+
"strings"
78

89
"github.com/BurntSushi/toml"
910
"github.com/pkg/errors"
@@ -70,7 +71,25 @@ type RunImageConfig struct {
7071

7172
// BuildConfig build image configuration
7273
type BuildConfig struct {
73-
Image string `toml:"image"`
74+
Image string `toml:"image"`
75+
Env []BuildConfigEnv `toml:"env"`
76+
}
77+
78+
type Suffix string
79+
80+
const (
81+
NONE Suffix = ""
82+
DEFAULT Suffix = "default"
83+
OVERRIDE Suffix = "override"
84+
APPEND Suffix = "append"
85+
PREPEND Suffix = "prepend"
86+
)
87+
88+
type BuildConfigEnv struct {
89+
Name string `toml:"name"`
90+
Value string `toml:"value"`
91+
Suffix Suffix `toml:"suffix,omitempty"`
92+
Delim string `toml:"delim,omitempty"`
7493
}
7594

7695
// ReadConfig reads a builder configuration from the file path provided and returns the
@@ -162,3 +181,92 @@ func parseConfig(file *os.File) (Config, error) {
162181

163182
return builderConfig, nil
164183
}
184+
185+
func ParseBuildConfigEnv(env []BuildConfigEnv, path string) (envMap map[string]string, warnings []string, err error) {
186+
envMap = map[string]string{}
187+
var appendOrPrependWithoutDelim = 0
188+
for _, v := range env {
189+
if name := v.Name; name == "" || len(name) == 0 {
190+
return nil, nil, errors.Wrapf(errors.Errorf("env name should not be empty"), "parse contents of '%s'", path)
191+
}
192+
if val := v.Value; val == "" || len(val) == 0 {
193+
warnings = append(warnings, fmt.Sprintf("empty value for key/name %s", style.Symbol(v.Name)))
194+
}
195+
suffixName, delimName, err := getBuildConfigEnvFileName(v)
196+
if err != nil {
197+
return envMap, warnings, err
198+
}
199+
if val, e := envMap[suffixName]; e {
200+
warnings = append(warnings, fmt.Sprintf(errors.Errorf("overriding env with name: %s and suffix: %s from %s to %s", style.Symbol(v.Name), style.Symbol(string(v.Suffix)), style.Symbol(val), style.Symbol(v.Value)).Error(), "parse contents of '%s'", path))
201+
}
202+
if val, e := envMap[delimName]; e {
203+
warnings = append(warnings, fmt.Sprintf(errors.Errorf("overriding env with name: %s and delim: %s from %s to %s", style.Symbol(v.Name), style.Symbol(v.Delim), style.Symbol(val), style.Symbol(v.Value)).Error(), "parse contents of '%s'", path))
204+
}
205+
if delim := v.Delim; (delim != "" || len(delim) != 0) && (delimName != "" || len(delimName) != 0) {
206+
envMap[delimName] = delim
207+
}
208+
envMap[suffixName] = v.Value
209+
}
210+
211+
for k := range envMap {
212+
name, suffix, err := getFilePrefixSuffix(k)
213+
if err != nil {
214+
continue
215+
}
216+
if _, ok := envMap[name+".delim"]; (suffix == "append" || suffix == "prepend") && !ok {
217+
warnings = append(warnings, fmt.Sprintf(errors.Errorf("env with name/key %s with suffix %s must to have a %s value", style.Symbol(name), style.Symbol(suffix), style.Symbol("delim")).Error(), "parse contents of '%s'", path))
218+
appendOrPrependWithoutDelim++
219+
}
220+
}
221+
if appendOrPrependWithoutDelim > 0 {
222+
return envMap, warnings, errors.Errorf("error parsing [[build.env]] in file '%s'", path)
223+
}
224+
return envMap, warnings, err
225+
}
226+
227+
func getBuildConfigEnvFileName(env BuildConfigEnv) (suffixName, delimName string, err error) {
228+
suffix, err := getActionType(env.Suffix)
229+
if err != nil {
230+
return suffixName, delimName, err
231+
}
232+
if suffix == "" {
233+
suffixName = env.Name
234+
} else {
235+
suffixName = env.Name + suffix
236+
}
237+
if delim := env.Delim; delim != "" || len(delim) != 0 {
238+
delimName = env.Name + ".delim"
239+
}
240+
return suffixName, delimName, err
241+
}
242+
243+
func getActionType(suffix Suffix) (suffixString string, err error) {
244+
const delim = "."
245+
switch suffix {
246+
case NONE:
247+
return "", nil
248+
case DEFAULT:
249+
return delim + string(DEFAULT), nil
250+
case OVERRIDE:
251+
return delim + string(OVERRIDE), nil
252+
case APPEND:
253+
return delim + string(APPEND), nil
254+
case PREPEND:
255+
return delim + string(PREPEND), nil
256+
default:
257+
return suffixString, errors.Errorf("unknown action type %s", style.Symbol(string(suffix)))
258+
}
259+
}
260+
261+
func getFilePrefixSuffix(filename string) (prefix, suffix string, err error) {
262+
val := strings.Split(filename, ".")
263+
if len(val) <= 1 {
264+
return val[0], suffix, errors.Errorf("Suffix might be null")
265+
}
266+
if len(val) == 2 {
267+
suffix = val[1]
268+
} else {
269+
suffix = strings.Join(val[1:], ".")
270+
}
271+
return val[0], suffix, err
272+
}

builder/config_reader_test.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,4 +229,111 @@ uri = "noop-buildpack.tgz"
229229
h.AssertError(t, builder.ValidateConfig(config), "build.image is required")
230230
})
231231
})
232+
when("#ParseBuildConfigEnv()", func() {
233+
it("should return an error when name is not defined", func() {
234+
_, _, err := builder.ParseBuildConfigEnv([]builder.BuildConfigEnv{
235+
{
236+
Name: "",
237+
Value: "vaiue",
238+
},
239+
}, "")
240+
h.AssertNotNil(t, err)
241+
})
242+
it("should warn when the value is nil or empty string", func() {
243+
env, warn, err := builder.ParseBuildConfigEnv([]builder.BuildConfigEnv{
244+
{
245+
Name: "key",
246+
Value: "",
247+
Suffix: "override",
248+
},
249+
}, "")
250+
251+
h.AssertNotNil(t, warn)
252+
h.AssertNil(t, err)
253+
h.AssertMapContains[string, string](t, env, h.NewKeyValue[string, string]("key.override", ""))
254+
})
255+
it("should return an error when unknown suffix is specified", func() {
256+
_, _, err := builder.ParseBuildConfigEnv([]builder.BuildConfigEnv{
257+
{
258+
Name: "key",
259+
Value: "",
260+
Suffix: "invalid",
261+
},
262+
}, "")
263+
264+
h.AssertNotNil(t, err)
265+
})
266+
it("should override and show a warning when suffix or delim is defined multiple times", func() {
267+
env, warn, err := builder.ParseBuildConfigEnv([]builder.BuildConfigEnv{
268+
{
269+
Name: "key1",
270+
Value: "value1",
271+
Suffix: "append",
272+
Delim: "%",
273+
},
274+
{
275+
Name: "key1",
276+
Value: "value2",
277+
Suffix: "append",
278+
Delim: ",",
279+
},
280+
{
281+
Name: "key1",
282+
Value: "value3",
283+
Suffix: "default",
284+
Delim: ";",
285+
},
286+
{
287+
Name: "key1",
288+
Value: "value4",
289+
Suffix: "prepend",
290+
Delim: ":",
291+
},
292+
}, "")
293+
294+
h.AssertNotNil(t, warn)
295+
h.AssertNil(t, err)
296+
h.AssertMapContains[string, string](
297+
t,
298+
env,
299+
h.NewKeyValue[string, string]("key1.append", "value2"),
300+
h.NewKeyValue[string, string]("key1.default", "value3"),
301+
h.NewKeyValue[string, string]("key1.prepend", "value4"),
302+
h.NewKeyValue[string, string]("key1.delim", ":"),
303+
)
304+
h.AssertMapNotContains[string, string](
305+
t,
306+
env,
307+
h.NewKeyValue[string, string]("key1.append", "value1"),
308+
h.NewKeyValue[string, string]("key1.delim", "%"),
309+
h.NewKeyValue[string, string]("key1.delim", ","),
310+
h.NewKeyValue[string, string]("key1.delim", ";"),
311+
)
312+
})
313+
it("should return an error when `suffix` is defined as `append` or `prepend` without a `delim`", func() {
314+
_, warn, err := builder.ParseBuildConfigEnv([]builder.BuildConfigEnv{
315+
{
316+
Name: "key",
317+
Value: "value",
318+
Suffix: "append",
319+
},
320+
}, "")
321+
322+
h.AssertNotNil(t, warn)
323+
h.AssertNotNil(t, err)
324+
})
325+
it("when suffix is NONE or omitted should default to `override`", func() {
326+
env, warn, err := builder.ParseBuildConfigEnv([]builder.BuildConfigEnv{
327+
{
328+
Name: "key",
329+
Value: "value",
330+
Suffix: "",
331+
},
332+
}, "")
333+
334+
h.AssertNotNil(t, warn)
335+
h.AssertNil(t, err)
336+
h.AssertMapContains[string, string](t, env, h.NewKeyValue[string, string]("key", "value"))
337+
})
338+
})
232339
}

0 commit comments

Comments
 (0)