Skip to content

Commit

Permalink
feat(RHTAPREL-849): add e2e test for release_to_github
Browse files Browse the repository at this point in the history
  • Loading branch information
jinqi7 committed Mar 18, 2024
1 parent c18b86c commit 7707c34
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 7 deletions.
2 changes: 1 addition & 1 deletion magefiles/magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ func (ci CI) TestE2E() error {
}

func RunE2ETests() error {
labelFilter := utils.GetEnv("E2E_TEST_SUITE_LABEL", "!upgrade-create && !upgrade-verify && !upgrade-cleanup && !release-pipelines")
labelFilter := utils.GetEnv("E2E_TEST_SUITE_LABEL", "!upgrade-create && !upgrade-verify && !upgrade-cleanup")
return runTests(labelFilter, "e2e-report.xml")
}

Expand Down
30 changes: 30 additions & 0 deletions pkg/clients/github/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,41 @@ package github
import (
"context"
"fmt"
"strings"

"github.com/google/go-github/v44/github"
. "github.com/onsi/ginkgo/v2"
)

func (g *Github) CheckIfReleaseExist(owner, repositoryName, releaseURL string) bool {
urlParts := strings.Split(releaseURL, "/")
tagName := urlParts[len(urlParts)-1]
_, _, err := g.client.Repositories.GetReleaseByTag(context.Background(), owner, repositoryName, tagName)
if err != nil {
GinkgoWriter.Printf("GetReleaseByTag %s returned error in repo %s : %v\n", tagName, repositoryName, err)
return false
}
GinkgoWriter.Printf("Release tag %s is found in repository %s \n", tagName, repositoryName)
return true
}

func (g *Github) DeleteRelease(owner, repositoryName, releaseURL string) bool {
urlParts := strings.Split(releaseURL, "/")
tagName := urlParts[len(urlParts)-1]
release, _, err := g.client.Repositories.GetReleaseByTag(context.Background(), owner, repositoryName, tagName)
if err != nil {
GinkgoWriter.Printf("GetReleaseByTag returned error in repo %s : %v\n", repositoryName, err)
return false
}

_, err = g.client.Repositories.DeleteRelease(context.Background(), owner, repositoryName, *release.ID)
if err != nil {
GinkgoWriter.Printf("DeleteRelease returned error: %v", err)
}
GinkgoWriter.Printf("Release tag %s is deleted in repository %s \n", tagName, repositoryName)
return true
}

func (g *Github) CheckIfRepositoryExist(repository string) bool {
_, resp, err := g.client.Repositories.Get(context.Background(), g.organization, repository)
if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions tests/release/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const (
ReleaseCreationTimeout = 5 * time.Minute
ReleasePipelineRunCreationTimeout = 10 * time.Minute
ReleasePipelineRunCompletionTimeout = 60 * time.Minute
BuildPipelineRunCompletionTimeout = 60 * time.Minute
BuildPipelineRunCreationTimeout = 10 * time.Minute
ReleasePlanStatusUpdateTimeout = 1 * time.Minute
DefaultInterval = 100 * time.Millisecond

Expand All @@ -37,6 +39,12 @@ const (
AdditionalReleasedImagePushRepo string = "quay.io/redhat-appstudio-qe/simplepython"
PyxisStageImagesApiEndpoint string = "https://pyxis.preprod.api.redhat.com/v1/images/id/"

// EC constants
EcPolicyLibPath = "github.com/enterprise-contract/ec-policies//policy/lib"
EcPolicyReleasePath = "github.com/enterprise-contract/ec-policies//policy/release"
EcPolicyDataBundle = "oci::quay.io/redhat-appstudio-tekton-catalog/data-acceptable-bundles:latest"
EcPolicyDataPath = "github.com/release-engineering/rhtap-ec-policy//data"

// Service constants
ApplicationName string = "application"
)
Expand Down
8 changes: 2 additions & 6 deletions tests/release/pipelines/fbc_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ const (
fbcSourceGitURL = "https://github.com/redhat-appstudio-qe/fbc-sample-repo"
targetPort = 50051
relSvcCatalogPathInRepo = "pipelines/fbc-release/fbc-release.yaml"
ecPolicyLibPath = "github.com/enterprise-contract/ec-policies//policy/lib"
ecPolicyReleasePath = "github.com/enterprise-contract/ec-policies//policy/release"
ecPolicyDataBundle = "oci::quay.io/redhat-appstudio-tekton-catalog/data-acceptable-bundles:latest"
ecPolicyDataPath = "github.com/release-engineering/rhtap-ec-policy//data"
)

var _ = framework.ReleasePipelinesSuiteDescribe("FBC e2e-tests", Label("release-pipelines", "fbc-tests"), func() {
Expand Down Expand Up @@ -294,8 +290,8 @@ func createFBCEnterpriseContractPolicy(fbcECPName string, managedFw framework.Fr
PublicKey: "k8s://openshift-pipelines/public-key",
Sources: []ecp.Source{{
Name: "Default",
Policy: []string{ecPolicyLibPath, ecPolicyReleasePath},
Data: []string{ecPolicyDataBundle, ecPolicyDataPath},
Policy: []string{releasecommon.EcPolicyLibPath, releasecommon.EcPolicyReleasePath},
Data: []string{releasecommon.EcPolicyDataBundle, releasecommon.EcPolicyDataPath},
}},
Configuration: &ecp.EnterpriseContractPolicyConfiguration{
Exclude: []string{"cve", "step_image_registries", "tasks.required_tasks_found:prefetch-dependencies"},
Expand Down
246 changes: 246 additions & 0 deletions tests/release/pipelines/release_to_github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package pipelines

import (
"encoding/json"
"fmt"
"os"
"time"

"github.com/devfile/library/v2/pkg/util"
ecp "github.com/enterprise-contract/enterprise-contract-controller/api/v1alpha1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
appservice "github.com/redhat-appstudio/application-api/api/v1alpha1"
"github.com/redhat-appstudio/e2e-tests/pkg/clients/github"
//"github.com/redhat-appstudio/e2e-tests/pkg/clients/has"
"github.com/redhat-appstudio/e2e-tests/pkg/constants"
"github.com/redhat-appstudio/e2e-tests/pkg/framework"
"github.com/redhat-appstudio/e2e-tests/pkg/utils"
"github.com/redhat-appstudio/e2e-tests/pkg/utils/tekton"
tektonv1"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
releaseapi "github.com/redhat-appstudio/release-service/api/v1alpha1"
releasecommon "github.com/redhat-appstudio/e2e-tests/tests/release"
tektonutils "github.com/redhat-appstudio/release-service/tekton/utils"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
rhcsServiceAccountName = "release-service-account"
rhcsSourceGitURL = "https://github.com/redhat-appstudio-qe/terraform-provider-rhcs"
rhcsReleaseURL = "https://github.com/redhat-appstudio-qe/terraform-provider-rhcs/releases/tag/v2.1"
rhcsRepoOwner = "redhat-appstudio-qe"
rhcsCatalogPathInRepo = "pipelines/release-to-github/release-to-github.yaml"
)

var _ = framework.ReleasePipelinesSuiteDescribe("e2e tests for release-to-github", Label("release-pipelines", "release-to-github"), func() {
defer GinkgoRecover()

var devWorkspace = utils.GetEnv(constants.RELEASE_DEV_WORKSPACE_ENV, constants.DevReleaseTeam)
var managedWorkspace = utils.GetEnv(constants.RELEASE_MANAGED_WORKSPACE_ENV, constants.ManagedReleaseTeam)

var devNamespace = devWorkspace + "-tenant"
var managedNamespace = managedWorkspace + "-tenant"

var err error
var devFw *framework.Framework
var managedFw *framework.Framework
var rhcsApplicationName = "rhcs-app-" + util.GenerateRandomString(4)
var rhcsComponentName = "rhcs-comp-" + util.GenerateRandomString(4)
var rhcsReleasePlanName = "rhcs-rp-" + util.GenerateRandomString(4)
var rhcsReleasePlanAdmissionName = "rhcs-rpa-" + util.GenerateRandomString(4)
var rhcsEnterpriseContractPolicyName = "rhcs-policy-" + util.GenerateRandomString(4)

var snapshot *appservice.Snapshot
var releaseCR *releaseapi.Release
var releasePR, buildPR *tektonv1.PipelineRun
var gh *github.Github

AfterEach(framework.ReportFailure(&devFw))

stageOptions := utils.Options{
ToolchainApiUrl: os.Getenv(constants.TOOLCHAIN_API_URL_ENV),
KeycloakUrl: os.Getenv(constants.KEYLOAK_URL_ENV),
OfflineToken: os.Getenv(constants.OFFLINE_TOKEN_ENV),
}

Describe("with RHCS happy path", Label("rhcsHappyPath"), func() {
var component *appservice.Component
BeforeAll(func() {

devFw, err = framework.NewFrameworkWithTimeout(
devWorkspace,
time.Minute*60,
stageOptions,
)
Expect(err).NotTo(HaveOccurred())

managedFw, err = framework.NewFrameworkWithTimeout(
managedWorkspace,
time.Minute*60,
stageOptions,
)
Expect(err).NotTo(HaveOccurred())
managedNamespace = managedFw.UserNamespace

// Linking the build secret to the pipeline service account in dev namespace.
err = devFw.AsKubeAdmin.CommonController.LinkSecretToServiceAccount(devNamespace, releasecommon.HacbsReleaseTestsTokenSecret, constants.DefaultPipelineServiceAccount, true)
Expect(err).ToNot(HaveOccurred())

githubUser := utils.GetEnv("GITHUB_USER","")
githubToken := utils.GetEnv(constants.GITHUB_TOKEN_ENV, "")
gh, err = github.NewGithubClient(githubToken, githubUser)
Expect(githubToken).ToNot(BeEmpty())
if gh.CheckIfReleaseExist(rhcsRepoOwner, "terraform-provider-rhcs", rhcsReleaseURL){
// Remove the release if the release exists
gh.DeleteRelease(rhcsRepoOwner, "terraform-provider-rhcs", rhcsReleaseURL)
}

_, err = managedFw.AsKubeAdmin.CommonController.GetSecret(managedNamespace, releasecommon.RedhatAppstudioUserSecret)
if errors.IsNotFound(err) {
githubSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: releasecommon.RedhatAppstudioUserSecret,
Namespace: managedNamespace,
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{
"token": []byte(githubToken),
},
}

_, err = managedFw.AsKubeAdmin.CommonController.CreateSecret(managedNamespace, githubSecret)
Expect(err).ToNot(HaveOccurred())
}
Expect(err).ToNot(HaveOccurred())

err = managedFw.AsKubeAdmin.CommonController.LinkSecretToServiceAccount(managedNamespace, releasecommon.RedhatAppstudioUserSecret, constants.DefaultPipelineServiceAccount, true)
Expect(err).ToNot(HaveOccurred())

_, err = devFw.AsKubeDeveloper.HasController.CreateApplication(rhcsApplicationName, devNamespace)
Expect(err).NotTo(HaveOccurred())

_, err = devFw.AsKubeDeveloper.ReleaseController.CreateReleasePlan(rhcsReleasePlanName, devNamespace, rhcsApplicationName, managedNamespace, "true")
Expect(err).NotTo(HaveOccurred())

createRHCSReleasePlanAdmission(rhcsReleasePlanAdmissionName, *managedFw, devNamespace, managedNamespace, rhcsApplicationName, rhcsEnterpriseContractPolicyName, rhcsCatalogPathInRepo, "false", "", "", "", "")
component = releasecommon.CreateComponentByCDQ(*devFw, devNamespace, managedNamespace, rhcsApplicationName, rhcsComponentName, rhcsSourceGitURL)
createRHCSEnterpriseContractPolicy(rhcsEnterpriseContractPolicyName, *managedFw, devNamespace, managedNamespace)

})

AfterAll(func() {
Expect(devFw.AsKubeDeveloper.HasController.DeleteApplication(rhcsApplicationName, devNamespace, false)).NotTo(HaveOccurred())
Expect(managedFw.AsKubeDeveloper.TektonController.DeleteEnterpriseContractPolicy(rhcsEnterpriseContractPolicyName, managedNamespace, false)).NotTo(HaveOccurred())
Expect(managedFw.AsKubeDeveloper.ReleaseController.DeleteReleasePlanAdmission(rhcsReleasePlanAdmissionName, managedNamespace, false)).NotTo(HaveOccurred())
})

var _ = Describe("Post-release verification", func() {
It("verifies that a build PipelineRun is created in dev namespace and succeeds", func() {
Eventually(func() error {
buildPR, err = devFw.AsKubeDeveloper.HasController.GetComponentPipelineRun(component.Name, rhcsApplicationName, devNamespace, "")
if err != nil {
return err
}
if !buildPR.IsDone() {
return fmt.Errorf("build pipelinerun %s in namespace %s did not finish yet", buildPR.Name, buildPR.Namespace)
}
Expect(tekton.HasPipelineRunSucceeded(buildPR)).To(BeTrue(), fmt.Sprintf("build pipelinerun %s/%s did not succeed", buildPR.GetNamespace(), buildPR.GetName()))
snapshot, err = devFw.AsKubeDeveloper.IntegrationController.GetSnapshot("", buildPR.Name, "", devNamespace)
Expect(err).ShouldNot(HaveOccurred())
return nil
}, releasecommon.BuildPipelineRunCompletionTimeout, releasecommon.DefaultInterval).Should(Succeed(), "timed out when waiting for build pipelinerun to be created")
//Expect(devFw.AsKubeDeveloper.HasController.WaitForComponentPipelineToBeFinished(component, "", devFw.AsKubeDeveloper.TektonController, &has.RetryOptions{Retries: 3, Always: true})).To(Succeed())
})
It("verifies the rhcs release pipelinerun is running and succeeds", func() {
releaseCR, err = devFw.AsKubeDeveloper.ReleaseController.GetRelease("", snapshot.Name, devNamespace)
Expect(err).ShouldNot(HaveOccurred())
Eventually(func() error {
releasePR, err = managedFw.AsKubeAdmin.ReleaseController.GetPipelineRunInNamespace(managedFw.UserNamespace, releaseCR.GetName(), releaseCR.GetNamespace())
if err != nil {
return err
}
Expect(err).ShouldNot(HaveOccurred())

if !releasePR.IsDone() {
return fmt.Errorf("release pipelinerun %s in namespace %s did not finish yet", releasePR.Name, releasePR.Namespace)
}
GinkgoWriter.Println("Release PR: ", releasePR.Name)
Expect(tekton.HasPipelineRunSucceeded(releasePR)).To(BeTrue(), fmt.Sprintf("release pipelinerun %s/%s did not succeed", releasePR.GetNamespace(), releasePR.GetName()))
return nil
}, releasecommon.ReleasePipelineRunCompletionTimeout, releasecommon.DefaultInterval).Should(Succeed(), "timed out when waiting for release pipelinerun to succeed")
})

It("verifies release CR completed and set succeeded.", func() {
Eventually(func() error {
releaseCR, err = devFw.AsKubeDeveloper.ReleaseController.GetRelease("", snapshot.Name, devNamespace)
if err != nil {
return err
}
GinkgoWriter.Println("Release CR: ", releaseCR.Name)
if !releaseCR.IsReleased() {
return fmt.Errorf("release %s/%s is not marked as finished yet", releaseCR.GetNamespace(), releaseCR.GetName())
}
return nil
}, releasecommon.ReleaseCreationTimeout, releasecommon.DefaultInterval).Should(Succeed())
})

It("verifies if the Release exists in github repo", func() {
trReleasePr, err := managedFw.AsKubeAdmin.TektonController.GetTaskRunStatus(managedFw.AsKubeAdmin.CommonController.KubeRest(), releasePR, "create-github-release")
Expect(err).NotTo(HaveOccurred())
trReleaseURL := trReleasePr.Status.TaskRunStatusFields.Results[0].Value.StringVal
Expect(trReleaseURL).To(Equal(rhcsReleaseURL))
Expect(gh.CheckIfReleaseExist(rhcsRepoOwner, "terraform-provider-rhcs", trReleaseURL)).To(BeTrue(), fmt.Sprintf("release %s doesn't exist", trReleaseURL))
})
})
})
})


func createRHCSEnterpriseContractPolicy(rhcsECPName string, managedFw framework.Framework, devNamespace, managedNamespace string) {
defaultEcPolicySpec := ecp.EnterpriseContractPolicySpec{
Description: "Red Hat's enterprise requirements",
PublicKey: "k8s://openshift-pipelines/public-key",
Sources: []ecp.Source{{
Name: "Default",
Policy: []string{releasecommon.EcPolicyLibPath, releasecommon.EcPolicyReleasePath},
Data: []string{releasecommon.EcPolicyDataBundle, releasecommon.EcPolicyDataPath},
}},
Configuration: &ecp.EnterpriseContractPolicyConfiguration{
Exclude: []string{"cve", "step_image_registries", "tasks.required_tasks_found:prefetch-dependencies"},
Include: []string{"minimal"},
},
}

_, err := managedFw.AsKubeDeveloper.TektonController.CreateEnterpriseContractPolicy(rhcsECPName, managedNamespace, defaultEcPolicySpec)
Expect(err).NotTo(HaveOccurred())

}

func createRHCSReleasePlanAdmission(rhcsRPAName string, managedFw framework.Framework, devNamespace, managedNamespace, rhcsAppName, rhcsECPName, pathInRepoValue, hotfix, issueId, preGA, productName, productVersion string) {
var err error

data, err := json.Marshal(map[string]interface{}{
"github": map[string]interface{}{
"githubSecret": releasecommon.RedhatAppstudioUserSecret,
},
"sign": map[string]interface{}{
"configMapName": "hacbs-signing-pipeline-config-redhatbeta2",
},
})
Expect(err).NotTo(HaveOccurred())

_, err = managedFw.AsKubeAdmin.ReleaseController.CreateReleasePlanAdmission(rhcsRPAName, managedNamespace, "", devNamespace, rhcsECPName, rhcsServiceAccountName, []string{rhcsAppName}, true, &tektonutils.PipelineRef{
Resolver: "git",
Params: []tektonutils.Param{
{Name: "url", Value: releasecommon.RelSvcCatalogURL},
{Name: "revision", Value: releasecommon.RelSvcCatalogRevision},
{Name: "pathInRepo", Value: pathInRepoValue},
},
}, &runtime.RawExtension{
Raw: data,
})
Expect(err).NotTo(HaveOccurred())
}

0 comments on commit 7707c34

Please sign in to comment.