opendevstack / ods-pipeline

Alternative ODS CI/CD pipeline based on Tekton / OpenShift Pipelines
Apache License 2.0
13 stars 5 forks source link

Refactor to ease development of tasks in external Git repositories #722

Closed michaelsauter closed 10 months ago

michaelsauter commented 12 months ago

Provide Go package(s) allowing to develop tasks easily in external Git repositories. Eventually, the goal is to extract the build / package / deploy tasks from this repo and have them in separate Git repositories with independent lifecycle.

Package tektontaskrun provides ODS Pipeline independent functionality to run Tekton tasks in a KinD cluster. The code is mostly copied from test/tasks/common_test.go and pkg/tasktesting. Package odstasktest builds on top of tektontaskrun and provides ODS Pipeline specific functionality to run ODS Pipeline tasks (e.g. installing ODS Pipeline, starting Nexus, etc.).

As a side-effect, the new approach allows to just run the Go tests without requiring to prepare any state upfront. All dependencies will be taken care of by the Go packages. As an example, here is how an external repo can use this:

// main_test.go
import (
    ott "github.com/opendevstack/ods-pipeline/pkg/odstasktest"
    ttr "github.com/opendevstack/ods-pipeline/pkg/tektontaskrun"
)

var namespaceConfig *ttr.NamespaceConfig

func TestMain(m *testing.M) {
    cc, err := ttr.StartKinDCluster(
        ttr.LoadImage(ttr.ImageBuildConfig{
            Dockerfile: "build/images/Dockerfile.go-toolset",
            ContextDir: rootPath,
        }),
    )
    if err != nil {
        log.Fatal("Could not start KinD cluster: ", err)
    }
    nc, cleanup, err := ttr.SetupTempNamespace(
        cc,
        ott.InstallODSPipeline(),
        ttr.InstallTaskFromPath(
            filepath.Join(rootPath, "build/tasks/ods-pipeline-v1-go-build.yaml"),
            nil,
        ),
    )
    if err != nil {
        log.Fatal("Could not setup temporary namespace: ", err)
    }
    defer cleanup()
    namespaceConfig = nc
    os.Exit(m.Run())
}
// go_build_test.go
import (
    ott "github.com/opendevstack/ods-pipeline/pkg/odstasktest"
    ttr "github.com/opendevstack/ods-pipeline/pkg/tektontaskrun"
)
func TestBuildGoTask(t *testing.T) {
    if err := ttr.RunTask(
                ttr.InNamespace(namespaceConfig.Name),
        ttr.UsingTask("ods-pipeline-v1-go-build"),
        ttr.WithStringParams(map[string]string{
            "go-os":       runtime.GOOS,
            "go-arch":     runtime.GOARCH,
            "cache-build": "false",
        }),
        withGoWorkspace(t, "go-sample-app"),
        ttr.AfterRun(func(config *ttr.TaskRunConfig, run *tekton.TaskRun) {
            wd := config.WorkspaceConfigs["source"].Dir
            cmd := exec.Command(wd + "/docker/app")
            b, err := cmd.Output()
            if err != nil {
                t.Fatal(err)
            }
            goProverb := "Don't communicate by sharing memory, share memory by communicating."
            if string(b) != goProverb {
                t.Fatalf("Got: %+v, want: %+v.", string(b), goProverb)
            }

            ott.AssertFilesExist(t, wd,
                "docker/Dockerfile",
                "docker/app",
                filepath.Join(pipelinectxt.LintReportsPath, "report.txt"),
                filepath.Join(pipelinectxt.XUnitReportsPath, "report.xml"),
                filepath.Join(pipelinectxt.CodeCoveragesPath, "coverage.out"),
            )
        }),
    ); err != nil {
        t.Fatal(err)
    }
}

...

This is still very much in progress.

For two examples using this PR, see https://github.com/BIX-Digital/ods-pipeline-go and https://github.com/BIX-Digital/ods-pipeline-sonar.

Closes #163

Tasks:

henrjk commented 10 months ago

My first impression is this is going in the right direction.

The example at https://github.com/BIX-Digital/ods-pipeline-go does not verify that with build caching the second run works. I believe the code could be adjusted to allow for this. Would this be the way forward or do you have other thoughts on how this would be addressed with the tasks in their own repo?

michaelsauter commented 10 months ago

My first impression is this is going in the right direction.

The example at https://github.com/BIX-Digital/ods-pipeline-go does not verify that with build caching the second run works. I believe the code could be adjusted to allow for this. Would this be the way forward or do you have other thoughts on how this would be addressed with the tasks in their own repo?

Cool!

I just left testing for build caching out to avoid initial effort. It should be possible to add this back in.

henrjk commented 10 months ago

I like to reaffirm that I find these changes to be a great improvement. Awesome work :rocket: Before eventually merging this let's ensure that we only expose things publicly that we are comfortable with. My suggestion is to continue to keep this in mind, and also dedicate a bit of work at the end to make it so.

michaelsauter commented 10 months ago

I have converted quite a few tasks (https://github.com/opendevstack/ods-pipeline-image, https://github.com/opendevstack/ods-pipeline-helm, https://github.com/opendevstack/ods-pipeline-npm, https://github.com/opendevstack/ods-pipeline-gradle, https://github.com/opendevstack/ods-pipeline-go, https://github.com/opendevstack/ods-pipeline-sonar) to this new structure and so far things are going smooth. However this is a lot of manual work so I am taking some shortcuts, e.g. just porting one test. Instead of waiting for everything to be fully done, I would merge this PR so that direction etc. is fully clear, and there is no duplicated work.

In regards to what is made public, you can browse the new packages at https://pkg.go.dev/github.com/opendevstack/ods-pipeline@v0.13.3-0.20230913064953-c7df840415df/pkg/tektontaskrun and https://pkg.go.dev/github.com/opendevstack/ods-pipeline@v0.13.3-0.20230913064953-c7df840415df/pkg/odstasktest. Is there anything in particular that you think should not be public?

Overall I think we are still pre-v1. I would expect some follow-up fixes from the refactoring that has been done, and once everything runs stable I think we can move the central repo to v1.

@henrjk What do you think?

henrjk commented 10 months ago

I have converted quite a few tasks (https://github.com/opendevstack/ods-pipeline-image, https://github.com/opendevstack/ods-pipeline-helm, https://github.com/opendevstack/ods-pipeline-npm, https://github.com/opendevstack/ods-pipeline-gradle, https://github.com/opendevstack/ods-pipeline-go, https://github.com/opendevstack/ods-pipeline-sonar) to this new structure and so far things are going smooth. However this is a lot of manual work so I am taking some shortcuts, e.g. just porting one test. Instead of waiting for everything to be fully done, I would merge this PR so that direction etc. is fully clear, and there is no duplicated work.

In regards to what is made public, you can browse the new packages at https://pkg.go.dev/github.com/opendevstack/ods-pipeline@v0.13.3-0.20230913064953-c7df840415df/pkg/tektontaskrun and https://pkg.go.dev/github.com/opendevstack/ods-pipeline@v0.13.3-0.20230913064953-c7df840415df/pkg/odstasktest. Is there anything in particular that you think should not be public?

Overall I think we are still pre-v1. I would expect some follow-up fixes from the refactoring that has been done, and once everything runs stable I think we can move the central repo to v1.

@henrjk What do you think?

👍 As we believe this is a much better way forward we should make this the mainline quickly. I expect it to take some more exposure to the wider ecosystem of tasks ods-pipeline can use with this before we should commit to a v1. We should also work on upgrading the kubernetes/tekton versions used soon to enable task compatibility, but in my mind at least this could be done quicker after this is merged.