Skip to content

Commit

Permalink
Add image-builder support for Jenkins (#12598)
Browse files Browse the repository at this point in the history
* Use GIT_COMMIT as pull request head for jenkins

* Add support for Jenkins

* Fix signing step success value

* Add ability to save report to file

* gomod(deps): bump github.com/spf13/pflag from 1.0.5 to 1.0.6 (#12599)

Bumps [github.com/spf13/pflag](https://github.com/spf13/pflag) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](spf13/pflag@v1.0.5...v1.0.6)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* gomod(deps): bump github.com/zricethezav/gitleaks/v8 (#12600)

Bumps [github.com/zricethezav/gitleaks/v8](https://github.com/zricethezav/gitleaks) from 8.23.2 to 8.23.3.
- [Release notes](https://github.com/zricethezav/gitleaks/releases)
- [Changelog](https://github.com/gitleaks/gitleaks/blob/master/.goreleaser.yml)
- [Commits](gitleaks/gitleaks@v8.23.2...v8.23.3)

---
updated-dependencies:
- dependency-name: github.com/zricethezav/gitleaks/v8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Wojciech Sołtys <[email protected]>

* gomod(deps): bump google.golang.org/api from 0.218.0 to 0.219.0 (#12601)

Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.218.0 to 0.219.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](googleapis/google-api-go-client@v0.218.0...v0.219.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bumping test-infra and testimages (#12603)

No eu.gcr.io/kyma-project/test-infra/ changes.

europe-docker.pkg.dev/kyma-project/prod/ changes: 67a01b6...45cbab5 (2025&#x2011;01&#x2011;24 → 2025&#x2011;01&#x2011;30)

* Bumping sec-scanners-config.yaml (#12606)

* Delete prow/jobs/kyma-project/test-infra/kyma-bot.yaml (#12607)

* Update config.yaml (#12604)

* Fix linter

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Wojciech Sołtys <[email protected]>
Co-authored-by: Kyma Bot <[email protected]>
  • Loading branch information
4 people authored Jan 30, 2025
1 parent b75245d commit e2cd0cf
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 137 deletions.
9 changes: 4 additions & 5 deletions cmd/image-builder/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ func loadJenkinsGitState(logger Logger) (GitStateConfig, error) {
return GitStateConfig{}, fmt.Errorf("failed to extract owner and repository from git URL %s: %w", gitURL, err)
}

// TODO(kacpermalachowski): For PRs this is a head commit, not a base commit.
// There is no reliable way to get the base commit SHA in Jenkins.
// See: https://github.tools.sap/kyma/oci-image-builder/issues/165
baseCommitSHA, present := os.LookupEnv("GIT_COMMIT")
if !present {
return GitStateConfig{}, fmt.Errorf("GIT_COMMIT environment variable is not set, please set it to valid commit SHA")
Expand All @@ -367,14 +370,10 @@ func loadJenkinsGitState(logger Logger) (GitStateConfig, error) {
if !present {
return GitStateConfig{}, fmt.Errorf("CHANGE_BRANCH environment variable is not set, please set it to valid base branch name")
}
pullRequestHeadSHA, present := os.LookupEnv("CHANGE_HEAD_SHA")
if !present {
return GitStateConfig{}, fmt.Errorf("CHANGE_HEAD_SHA environment variable is not set, please set it to valid commit SHA")
}
gitState.JobType = "presubmit"
gitState.PullRequestNumber = pullNumber
gitState.BaseCommitRef = baseRef
gitState.PullHeadCommitSHA = pullRequestHeadSHA
gitState.PullHeadCommitSHA = baseCommitSHA
gitState.isPullRequest = true
}

Expand Down
15 changes: 7 additions & 8 deletions cmd/image-builder/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,11 @@ func TestLoadGitStateConfig(t *testing.T) {
ciSystem: Jenkins,
},
env: map[string]string{
"CHANGE_BRANCH": "refs/heads/main",
"JENKINS_HOME": "/some/absolute/path",
"CHANGE_ID": "14",
"GIT_URL": "github.com/kyma-project/test-infra.git",
"GIT_COMMIT": "1234",
"CHANGE_HEAD_SHA": "4321", // Must be explicitly set when calling docker run
"CHANGE_BRANCH": "refs/heads/main",
"JENKINS_HOME": "/some/absolute/path",
"CHANGE_ID": "14",
"GIT_URL": "github.com/kyma-project/test-infra.git",
"GIT_COMMIT": "1234",
},
gitState: GitStateConfig{
RepositoryName: "test-infra",
Expand All @@ -418,7 +417,7 @@ func TestLoadGitStateConfig(t *testing.T) {
BaseCommitSHA: "1234",
BaseCommitRef: "refs/heads/main",
PullRequestNumber: 14,
PullHeadCommitSHA: "4321",
PullHeadCommitSHA: "1234",
isPullRequest: true,
},
},
Expand Down Expand Up @@ -520,4 +519,4 @@ func Test_determineCISystem(t *testing.T) {
}
})
}
}
}
57 changes: 32 additions & 25 deletions cmd/image-builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ import (
"os/exec"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"

adopipelines "github.com/kyma-project/test-infra/pkg/azuredevops/pipelines"
"github.com/kyma-project/test-infra/pkg/extractimageurls"
"github.com/kyma-project/test-infra/pkg/github/actions"
"github.com/kyma-project/test-infra/pkg/imagebuilder"
"github.com/kyma-project/test-infra/pkg/logging"
"github.com/kyma-project/test-infra/pkg/sets"
"github.com/kyma-project/test-infra/pkg/sign"
Expand Down Expand Up @@ -65,6 +64,12 @@ type options struct {
dryRun bool
tagsOutputFile string
useGoInternalSAPModules bool
// buildReportPath is a path to the file where the build report will be saved
// build report will be used by SRE team to gather information about the build
buildReportPath string
// adoStateOutput indicates if the success or failure of the command (sign or build) should be
// reported as an output variable in Azure DevOps
adoStateOutput bool
}

type Logger interface {
Expand Down Expand Up @@ -330,6 +335,7 @@ func buildInADO(o options) error {
var (
pipelineRunResult *pipelines.RunResult
logs string
buildReport *imagebuilder.BuildReport
)
if !o.dryRun {
ctx := context.Background()
Expand Down Expand Up @@ -371,6 +377,12 @@ func buildInADO(o options) error {
} else {
fmt.Printf("ADO pipeline image build logs:\n%s", logs)
}

// Parse the build report from the ADO pipeline run logs.
buildReport, err = imagebuilder.NewBuildReportFromLogs(logs)
if err != nil {
return fmt.Errorf("build in ADO failed, failed parsing build report from ADO pipeline run logs, err: %s", err)
}
} else {
dryRunPipelineRunResult := pipelines.RunResult("Succeeded")
pipelineRunResult = &dryRunPipelineRunResult
Expand All @@ -381,9 +393,8 @@ func buildInADO(o options) error {
// if run in github actions, set output parameters
if o.ciSystem == GithubActions {
fmt.Println("Setting GitHub outputs.")
var images []string
images := buildReport.GetImages()
if !o.dryRun {
images = extractImagesFromADOLogs(logs)
fmt.Printf("Extracted built images from ADO logs: %v\n", images)
} else {
fmt.Println("Running in dry-run mode. Skipping extracting images and results from ADO.")
Expand All @@ -406,6 +417,13 @@ func buildInADO(o options) error {
fmt.Println("adoResult GitHub output set")
}

if o.buildReportPath != "" {
err = imagebuilder.WriteReportToFile(buildReport, o.buildReportPath)
if err != nil {
return fmt.Errorf("failed writing build report to file: %w", err)
}
}

// Handle the ADO pipeline run failure.
if *pipelineRunResult == pipelines.RunResultValues.Failed || *pipelineRunResult == pipelines.RunResultValues.Unknown {
return fmt.Errorf("build in ADO finished with status: %s", *pipelineRunResult)
Expand Down Expand Up @@ -841,6 +859,8 @@ func (o *options) gatherOptions(flagSet *flag.FlagSet) *flag.FlagSet {
flagSet.StringVar(&o.azureAccessToken, "azure-access-token", "", "Token used to authenticate against Azure DevOps API")
flagSet.StringVar(&o.tagsOutputFile, "tags-output-file", "/generated-tags.json", "Path to file where generated tags will be written as JSON")
flagSet.BoolVar(&o.useGoInternalSAPModules, "use-go-internal-sap-modules", false, "Allow access to Go internal modules in ADO backend")
flagSet.StringVar(&o.buildReportPath, "build-report-path", "", "Path to file where build report will be written as JSON")
flagSet.BoolVar(&o.adoStateOutput, "ado-state-output", false, "Set output variables with result of image-buidler exececution")

return flagSet
}
Expand Down Expand Up @@ -904,9 +924,17 @@ func main() {
if o.signOnly {
err = signImages(&o, o.imagesToSign)
if err != nil {
if o.adoStateOutput {
adopipelines.SetVariable("signing_success", false, false, true)
}

fmt.Println(err)
os.Exit(1)
}

if o.adoStateOutput {
adopipelines.SetVariable("signing_success", true, false, true)
}
os.Exit(0)
}

Expand Down Expand Up @@ -1102,24 +1130,3 @@ func getDockerfileDirPath(logger Logger, o options) (string, error) {
logger.Debugw("dockerfile directory path constructed", "dockerfileDirPath", dockerfileDirPath)
return dockerfileDirPath, err
}

// extractImagesFromADOLogs extract docker images from Azure DevOps logs to allow us prepare list of images built in ADO backend
// The list can be than saved and provided as input for developers to use in next steps of their workflows.
// ADO Logs that we fetch anyway are the simplest solution to get such list from ADO backend.
func extractImagesFromADOLogs(logs string) []string {
re := regexp.MustCompile(`--images-to-sign=(([a-z0-9]+(?:[.-][a-z0-9]+)*/)*([a-z0-9]+(?:[.-][a-z0-9]+)*)(?::[a-z0-9.-]+)?/([a-z0-9-]+)/([a-z0-9-]+)(?::[a-zA-Z0-9.-]+))`)
matches := re.FindAllStringSubmatch(logs, -1)

images := []string{}
if len(matches) > 0 {
for _, match := range matches {
if len(match) > 1 {
images = append(images, match[1])
}
}
}

images = extractimageurls.UniqueImages(images)

return images
}
99 changes: 0 additions & 99 deletions cmd/image-builder/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -870,105 +870,6 @@ func Test_prepareADOTemplateParameters(t *testing.T) {
}
}

func Test_extractImagesFromADOLogs(t *testing.T) {
tc := []struct {
name string
expectedImages []string
logs string
}{
{
name: "sign image task log",
expectedImages: []string{"europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10854", "europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10852"},
logs: `2024-05-28T09:49:07.8176591Z ==============================================================================
2024-05-28T09:49:07.8176701Z Task : Docker
2024-05-28T09:49:07.8176776Z Description : Build or push Docker images, login or logout, start or stop containers, or run a Docker command
2024-05-28T09:49:07.8176902Z Version : 2.240.2
2024-05-28T09:49:07.8176962Z Author : Microsoft Corporation
2024-05-28T09:49:07.8177044Z Help : https://aka.ms/azpipes-docker-tsg
2024-05-28T09:49:07.8177121Z ==============================================================================
2024-05-28T09:49:08.2220004Z [command]/usr/bin/docker run --env REPO_NAME=test-infra --env REPO_OWNER=kyma-project --env CI=true --env JOB_TYPE=presubmit --mount type=bind,src=/agent/_work/1/s/kaniko-build-config.yaml,dst=/kaniko-build-config.yaml --mount type=bind,src=/agent/_work/1/s/signify-prod-secret.yaml,dst=/secret-prod/secret.yaml europe-docker.pkg.dev/kyma-project/prod/image-builder:v20240515-f756e622 --sign-only --name=image-builder --context=. --dockerfile=cmd/image-builder/images/kaniko/Dockerfile --images-to-sign=europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10854 --images-to-sign=europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10852 --config=/kaniko-build-config.yaml
2024-05-28T09:49:08.4547604Z sign images using services signify-prod
2024-05-28T09:49:08.4548507Z signer signify-prod ignored, because is not enabled for a CI job of type: presubmit
2024-05-28T09:49:08.4549247Z Start signing images europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10854
2024-05-28T09:49:08.5907215Z ##[section]Finishing: sign_images`,
},
{
name: "prepare args and sign tasks log",
expectedImages: []string{"europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10696"},
logs: `2024-05-28T07:36:31.8953681Z ##[section]Starting: prepare_build_and_sign_args
2024-05-28T07:36:31.8958057Z ==============================================================================
2024-05-28T07:36:31.8958168Z Task : Python script
2024-05-28T07:36:31.8958230Z Description : Run a Python file or inline script
2024-05-28T07:36:31.8958324Z Version : 0.237.1
2024-05-28T07:36:31.8958385Z Author : Microsoft Corporation
2024-05-28T07:36:31.8958459Z Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/python-script
2024-05-28T07:36:31.8958587Z ==============================================================================
2024-05-28T07:36:33.6944350Z [command]/usr/bin/python /agent/_work/1/s/scripts/prepare_kaniko_and_sign_arguments.py --PreparedTagsFile /agent/_work/_temp/task_outputs/run_1716881791884.txt --ExportTags False --JobType presubmit --Context . --Dockerfile cmd/image-builder/images/kaniko/Dockerfile --ImageName image-builder --BuildArgs --Platforms --BuildConfigPath /agent/_work/1/s/kaniko-build-config.yaml
2024-05-28T07:36:33.7426177Z ##[command]Read build config file:
2024-05-28T07:36:33.7426567Z ##[group]Build config file content:
2024-05-28T07:36:33.7430240Z ##[debug] {'tag-template': 'v{{ .Date }}-{{ .ShortSHA }}', 'registry': ['europe-docker.pkg.dev/kyma-project/prod'], 'dev-registry': ['europe-docker.pkg.dev/kyma-project/dev'], 'reproducible': False, 'log-format': 'json', 'ado-config': {'ado-organization-url': 'https://dev.azure.com/hyperspace-pipelines', 'ado-project-name': 'kyma', 'ado-pipeline-id': 14902}, 'cache': {'enabled': True, 'cache-repo': 'europe-docker.pkg.dev/kyma-project/cache/cache', 'cache-run-layers': True}, 'sign-config': {'enabled-signers': {'*': ['signify-prod']}, 'signers': [{'name': 'signify-prod', 'type': 'notary', 'job-type': ['postsubmit'], 'config': {'endpoint': 'https://signing.repositories.cloud.sap/signingsvc/sign', 'timeout': '5m', 'retry-timeout': '10s', 'secret': {'path': '/secret-prod/secret.yaml', 'type': 'signify'}}}]}}
2024-05-28T07:36:33.7431327Z ##[endgroup]
2024-05-28T07:36:33.7431542Z Running in presubmit mode
2024-05-28T07:36:33.7432035Z ##[debug]Using dev registries: ['europe-docker.pkg.dev/kyma-project/dev']
2024-05-28T07:36:33.7432334Z ##[debug]Using build context: .
2024-05-28T07:36:33.7432779Z ##[debug]Using Dockerfile: ./cmd/image-builder/images/kaniko/Dockerfile
2024-05-28T07:36:33.7433181Z ##[debug]Using image name: image-builder
2024-05-28T07:36:33.7433438Z ##[command]Using prepared OCI image tags:
2024-05-28T07:36:33.7433924Z ##[debug]Prepared tags file content: [{"name":"default_tag","value":"PR-10696"}]
2024-05-28T07:36:33.7434608Z
2024-05-28T07:36:33.7435959Z ##[command]Setting job scope pipeline variable kanikoArgs with value: --cache=True --cache-run-layers=True --cache-repo=europe-docker.pkg.dev/kyma-project/cache/cache --context=dir:///workspace/. --dockerfile=/workspace/./cmd/image-builder/images/kaniko/Dockerfile --build-arg=default_tag=PR-10696 --destination=europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10696
2024-05-28T07:36:33.7438292Z ##[command]Setting job scope pipeline variable imagesToSign with value: --images-to-sign=europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10696
2024-05-28T07:36:33.7496968Z
2024-05-28T07:36:33.7549637Z ##[section]Finishing: prepare_build_and_sign_args
2024-05-28T07:38:12.4360275Z ##[section]Starting: sign_images
2024-05-28T07:38:12.4364459Z ==============================================================================
2024-05-28T07:38:12.4364568Z Task : Docker
2024-05-28T07:38:12.4364645Z Description : Build or push Docker images, login or logout, start or stop containers, or run a Docker command
2024-05-28T07:38:12.4364762Z Version : 2.240.2
2024-05-28T07:38:12.4364823Z Author : Microsoft Corporation
2024-05-28T07:38:12.4364906Z Help : https://aka.ms/azpipes-docker-tsg
2024-05-28T07:38:12.4364993Z ==============================================================================
2024-05-28T07:38:12.8400661Z [command]/usr/bin/docker run --env REPO_NAME=test-infra --env REPO_OWNER=kyma-project --env CI=true --env JOB_TYPE=presubmit --mount type=bind,src=/agent/_work/1/s/kaniko-build-config.yaml,dst=/kaniko-build-config.yaml --mount type=bind,src=/agent/_work/1/s/signify-prod-secret.yaml,dst=/secret-prod/secret.yaml europe-docker.pkg.dev/kyma-project/prod/image-builder:v20240515-f756e622 --sign-only --name=image-builder --context=. --dockerfile=cmd/image-builder/images/kaniko/Dockerfile --images-to-sign=europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10696 --config=/kaniko-build-config.yaml
2024-05-28T07:38:13.0389131Z sign images using services signify-prod
2024-05-28T07:38:13.0389670Z signer signify-prod ignored, because is not enabled for a CI job of type: presubmit
2024-05-28T07:38:13.0390290Z Start signing images europe-docker.pkg.dev/kyma-project/dev/image-builder:PR-10696
2024-05-28T07:38:13.1669325Z ##[section]Finishing: sign_images`,
},
{
name: "prepare args and sign tasks logs only",
expectedImages: []string{"europe-docker.pkg.dev/kyma-project/dev/serverless-operator/ga:PR-1043"},
logs: `2024-07-03T09:04:35.8674788Z ##[section]Starting: prepare_build_and_sign_args
2024-07-03T09:04:35.8681603Z ==============================================================================
2024-07-03T09:04:35.8681824Z Task : Python script
2024-07-03T09:04:35.8681947Z Description : Run a Python file or inline script
2024-07-03T09:04:35.8682099Z Version : 0.237.1
2024-07-03T09:04:35.8682232Z Author : Microsoft Corporation
2024-07-03T09:04:35.8682356Z Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/python-script
2024-07-03T09:04:35.8682540Z ==============================================================================
2024-07-03T09:04:37.5031097Z [command]/usr/bin/python /agent/_work/1/s/scripts/prepare_kaniko_and_sign_arguments.py --PreparedTagsFile /agent/_work/_temp/task_outputs/run_1719997475854.txt --ExportTags False --JobType presubmit --Context . --Dockerfile components/operator/Dockerfile --ImageName serverless-operator/ga --BuildArgs --Platforms --BuildConfigPath /agent/_work/1/s/kaniko-build-config.yaml
2024-07-03T09:04:37.5527518Z ##[command]Read build config file:
Build config file content:
2024-07-03T09:04:37.5533715Z Running in presubmit mode
2024-07-03T09:04:37.5536685Z ##[command]Using prepared OCI image tags:
2024-07-03T09:04:37.5537692Z
2024-07-03T09:04:37.5539311Z ##[command]Setting job scope pipeline variable kanikoArgs with value: --cache=True --cache-run-layers=True --cache-repo=europe-docker.pkg.dev/kyma-project/cache/cache --context=dir:///repository/. --dockerfile=/repository/./components/operator/Dockerfile --build-arg=default_tag=PR-1043 --destination=europe-docker.pkg.dev/kyma-project/dev/serverless-operator/ga:PR-1043
2024-07-03T09:04:37.5542470Z ##[command]Setting job scope pipeline variable imagesToSign with value: --images-to-sign=europe-docker.pkg.dev/kyma-project/dev/serverless-operator/ga:PR-1043
2024-07-03T09:04:37.5597039Z
2024-07-03T09:04:37.5659445Z ##[section]Finishing: prepare_build_and_sign_args`,
},
}

for _, c := range tc {
t.Run(c.name, func(t *testing.T) {
actualImages := extractImagesFromADOLogs(c.logs)

if !reflect.DeepEqual(actualImages, c.expectedImages) {
t.Errorf("Expected %v, but got %v", c.expectedImages, actualImages)
}
})
}
}

type mockSignerFactory struct{}

func (m *mockSignerFactory) NewSigner() (sign.Signer, error) {
Expand Down
7 changes: 7 additions & 0 deletions pkg/azuredevops/pipelines/variables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package pipelines

import "fmt"

func SetVariable(name string, value interface{}, isSecret bool, isOutput bool) {
fmt.Printf("##vso[task.setvariable variable=%s;issecret=%v;isoutput=%v]%v\n", name, isSecret, isOutput, value)
}
71 changes: 71 additions & 0 deletions pkg/imagebuilder/report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package imagebuilder

import (
"encoding/json"
"fmt"
"os"
"regexp"
)

// reportRegex is a regular expression that matches the image build report
var reportRegex = regexp.MustCompile(`(?s)---IMAGE BUILD REPORT---\n(.*)\n---END OF IMAGE BUILD REPORT---`)

type BuildReport struct {
Status string `json:"status"`
IsSigned bool `json:"signed"`
IsProduction bool `json:"is_production"`
ImageSpec ImageSpec `json:"image_spec"`
}

type ImageSpec struct {
Name string `json:"image_name"`
Tags []string `json:"tags"`
RepositoryPath string `json:"repository_path"`
}

func (br *BuildReport) GetImages() []string {
var images []string

if br == nil {
return images
}

for _, tag := range br.ImageSpec.Tags {
images = append(images, fmt.Sprintf("%s%s:%s", br.ImageSpec.RepositoryPath, br.ImageSpec.Name, tag))
}

return images
}

func NewBuildReportFromLogs(log string) (*BuildReport, error) {
matches := reportRegex.FindStringSubmatch(log)
if len(matches) < 2 {
return nil, nil
}

var report BuildReport
if err := json.Unmarshal([]byte(matches[1]), &report); err != nil {
return nil, err
}

return &report, nil
}

func WriteReportToFile(report *BuildReport, path string) error {
data, err := json.Marshal(report)
if err != nil {
return fmt.Errorf("failed to marshal report: %w", err)
}

file, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
defer file.Close()

if _, err := file.Write(data); err != nil {
return fmt.Errorf("failed to write report to file: %w", err)
}

return nil
}
13 changes: 13 additions & 0 deletions pkg/imagebuilder/report_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package imagebuilder

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestPipelines(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Image Builder Suite")
}
Loading

0 comments on commit e2cd0cf

Please sign in to comment.