mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-03-03 15:02:35 +02:00
cnbBuild: support for zip archives as path argument (#3123)
This commit is contained in:
parent
0978f1492a
commit
61b33ec66e
113
cmd/cnbBuild.go
113
cmd/cnbBuild.go
@ -1,6 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -88,6 +89,70 @@ func isBuilder(utils cnbutils.BuildUtils) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func isZip(path string) bool {
|
||||
r, err := zip.OpenReader(path)
|
||||
|
||||
switch {
|
||||
case err == nil:
|
||||
r.Close()
|
||||
return true
|
||||
case err == zip.ErrFormat:
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func copyProject(source, target string, utils cnbutils.BuildUtils) error {
|
||||
sourceFiles, _ := utils.Glob(path.Join(source, "**"))
|
||||
for _, sourceFile := range sourceFiles {
|
||||
if !isIgnored(sourceFile) {
|
||||
target := path.Join(target, strings.ReplaceAll(sourceFile, source, ""))
|
||||
dir, err := isDir(sourceFile)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Checking file info '%s' failed", target)
|
||||
}
|
||||
|
||||
if dir {
|
||||
err = utils.MkdirAll(target, os.ModePerm)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Creating directory '%s' failed", target)
|
||||
}
|
||||
} else {
|
||||
log.Entry().Debugf("Copying '%s' to '%s'", sourceFile, target)
|
||||
_, err = utils.Copy(sourceFile, target)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Copying '%s' to '%s' failed", sourceFile, target)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Entry().Debugf("Filtered out '%s'", sourceFile)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyFile(source, target string, utils cnbutils.BuildUtils) error {
|
||||
|
||||
if isZip(source) {
|
||||
log.Entry().Infof("Extracting archive '%s' to '%s'", source, target)
|
||||
_, err := piperutils.Unzip(source, target)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Extracting archive '%s' to '%s' failed", source, target)
|
||||
}
|
||||
} else {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.New("application path must be a directory or zip")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, utils cnbutils.BuildUtils, commonPipelineEnvironment *cnbBuildCommonPipelineEnvironment) error {
|
||||
var err error
|
||||
|
||||
@ -140,33 +205,23 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
source = config.Path
|
||||
}
|
||||
|
||||
sourceFiles, _ := utils.Glob(path.Join(source, "**"))
|
||||
for _, sourceFile := range sourceFiles {
|
||||
if !isIgnored(sourceFile) {
|
||||
target := path.Join(target, strings.ReplaceAll(sourceFile, source, ""))
|
||||
dir, err := isDir(sourceFile)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Checking file info '%s' failed", target)
|
||||
}
|
||||
dir, err := isDir(source)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Checking file info '%s' failed", target)
|
||||
}
|
||||
|
||||
if dir {
|
||||
err = utils.MkdirAll(target, os.ModePerm)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Creating directory '%s' failed", target)
|
||||
}
|
||||
} else {
|
||||
log.Entry().Debugf("Copying '%s' to '%s'", sourceFile, target)
|
||||
_, err = utils.Copy(sourceFile, target)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Copying '%s' to '%s' failed", sourceFile, target)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
log.Entry().Debugf("Filtered out '%s'", sourceFile)
|
||||
if dir {
|
||||
err = copyProject(source, target, utils)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Copying '%s' into '%s' failed", source, target)
|
||||
}
|
||||
} else {
|
||||
err = copyFile(source, target, utils)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrapf(err, "Copying '%s' into '%s' failed", source, target)
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,20 +266,20 @@ func runCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData, u
|
||||
err = utils.RunExecutable(detectorPath, "-buildpacks", buildpacksPath, "-order", orderPath)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrap(err, fmt.Sprintf("execution of '%s' failed", detectorPath))
|
||||
return errors.Wrapf(err, "execution of '%s' failed", detectorPath)
|
||||
}
|
||||
|
||||
err = utils.RunExecutable(builderPath, "-buildpacks", buildpacksPath)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrap(err, fmt.Sprintf("execution of '%s' failed", builderPath))
|
||||
return errors.Wrapf(err, "execution of '%s' failed", builderPath)
|
||||
}
|
||||
|
||||
utils.AppendEnv([]string{fmt.Sprintf("CNB_REGISTRY_AUTH=%s", string(cnbRegistryAuth))})
|
||||
err = utils.RunExecutable(exporterPath, fmt.Sprintf("%s:%s", containerImage, containerImageTag), fmt.Sprintf("%s:latest", containerImage))
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorBuild)
|
||||
return errors.Wrap(err, fmt.Sprintf("execution of '%s' failed", exporterPath))
|
||||
return errors.Wrapf(err, "execution of '%s' failed", exporterPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -137,7 +137,7 @@ func addCnbBuildFlags(cmd *cobra.Command, stepConfig *cnbBuildOptions) {
|
||||
cmd.Flags().StringVar(&stepConfig.ContainerImageTag, "containerImageTag", os.Getenv("PIPER_containerImageTag"), "Tag of the container which will be built")
|
||||
cmd.Flags().StringVar(&stepConfig.ContainerRegistryURL, "containerRegistryUrl", os.Getenv("PIPER_containerRegistryUrl"), "Container registry where the image should be pushed to")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.Buildpacks, "buildpacks", []string{}, "List of custom buildpacks to use in the form of '<hostname>/<repo>[:<tag>]'.")
|
||||
cmd.Flags().StringVar(&stepConfig.Path, "path", os.Getenv("PIPER_path"), "The path should either point to your sources or an artifact build before.")
|
||||
cmd.Flags().StringVar(&stepConfig.Path, "path", os.Getenv("PIPER_path"), "The path should either point to a directory with your sources or an artifact in zip format.")
|
||||
cmd.Flags().StringVar(&stepConfig.DockerConfigJSON, "dockerConfigJSON", os.Getenv("PIPER_dockerConfigJSON"), "Path to the file `.docker/config.json` - this is typically provided by your CI/CD system. You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).")
|
||||
|
||||
cmd.MarkFlagRequired("containerImageName")
|
||||
|
@ -1,4 +1,6 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
// can be execute with go test -tags=integration ./integration/...
|
||||
|
||||
package main
|
||||
@ -23,6 +25,35 @@ func TestNpmProject(t *testing.T) {
|
||||
container.assertHasOutput(t, "failed to write image to the following tags: [test/not-found:0.0.1")
|
||||
}
|
||||
|
||||
func TestZipPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{
|
||||
Image: "paketobuildpacks/builder:full",
|
||||
User: "cnb",
|
||||
TestDir: []string{"testdata", "TestCnbIntegration", "zip"},
|
||||
})
|
||||
|
||||
container.whenRunningPiperCommand("cnbBuild", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", "test", "--path", "go.zip")
|
||||
|
||||
container.assertHasOutput(t, "running command: /cnb/lifecycle/detector")
|
||||
container.assertHasOutput(t, "Installing Go")
|
||||
container.assertHasOutput(t, "Paketo Go Build Buildpack")
|
||||
container.assertHasOutput(t, "Saving test/not-found:0.0.1")
|
||||
}
|
||||
|
||||
func TestNonZipPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{
|
||||
Image: "paketobuildpacks/builder:full",
|
||||
User: "cnb",
|
||||
TestDir: []string{"testdata", "TestMtaIntegration", "npm"},
|
||||
})
|
||||
|
||||
container.whenRunningPiperCommand("cnbBuild", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", "test", "--path", "mta.yaml")
|
||||
|
||||
container.assertHasOutput(t, "Copying 'mta.yaml' into '/workspace' failed: application path must be a directory or zip")
|
||||
}
|
||||
|
||||
func TestNpmCustomBuildpacksFullProject(t *testing.T) {
|
||||
t.Parallel()
|
||||
container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{
|
||||
|
BIN
integration/testdata/TestCnbIntegration/zip/go.zip
vendored
Normal file
BIN
integration/testdata/TestCnbIntegration/zip/go.zip
vendored
Normal file
Binary file not shown.
@ -57,7 +57,7 @@ spec:
|
||||
- STEPS
|
||||
- name: path
|
||||
type: string
|
||||
description: The path should either point to your sources or an artifact build before.
|
||||
description: The path should either point to a directory with your sources or an artifact in zip format.
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
|
Loading…
x
Reference in New Issue
Block a user