Skip to content

Commit

Permalink
Merge pull request #6 from thepetk/feature/add_nightly_run
Browse files Browse the repository at this point in the history
Feature/add nightly run
  • Loading branch information
thepetk authored Jul 27, 2023
2 parents 7f521b2 + b6633e5 commit aca6e69
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 5 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/check_registry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
on:
schedule:
- cron: "*/5 * * * *"

name: Production & Community Registries Check

defaults:
run:
shell: bash

permissions:
contents: write

jobs:
check-registry:
name: Check registry entries
runs-on: 'ubuntu-latest'
outputs:
matrix: ${{ steps.get-stacks.outputs.matrix }}
steps:
- name: Checkout code
id: checkout-code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup go
id: setup-go
uses: actions/setup-go@v4
with:
go-version: '1.19.5'
- name: Run registries check
id: build
run: |
go build alizer.go
bash test/check_registry/check_registry.sh
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/stretchr/testify v1.8.1
go.uber.org/zap v1.24.0
golang.org/x/mod v0.11.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
sigs.k8s.io/controller-runtime v0.15.0
)
Expand Down Expand Up @@ -55,7 +56,6 @@ require (
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/apimachinery v0.27.3 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
Expand Down
8 changes: 4 additions & 4 deletions pkg/apis/recognizer/devfile_recognizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func MatchDevfiles(path string, url string, filter model.DevfileFilter) ([]model
alizerLogger := utils.GetOrCreateLogger()
alizerLogger.V(0).Info("Starting devfile matching")
alizerLogger.V(1).Info(fmt.Sprintf("Downloading devfiles from registry %s", url))
devFileTypesFromRegistry, err := downloadDevFileTypesFromRegistry(url, filter)
devFileTypesFromRegistry, err := DownloadDevFileTypesFromRegistry(url, filter)
if err != nil {
return []model.DevFileType{}, err
}
Expand All @@ -121,7 +121,7 @@ func SelectDevFilesFromRegistry(path string, url string) ([]model.DevFileType, e
alizerLogger := utils.GetOrCreateLogger()
alizerLogger.V(0).Info("Starting devfile matching")
alizerLogger.V(1).Info(fmt.Sprintf("Downloading devfiles from registry %s", url))
devFileTypesFromRegistry, err := downloadDevFileTypesFromRegistry(url, model.DevfileFilter{MinSchemaVersion: "", MaxSchemaVersion: ""})
devFileTypesFromRegistry, err := DownloadDevFileTypesFromRegistry(url, model.DevfileFilter{MinSchemaVersion: "", MaxSchemaVersion: ""})
if err != nil {
return []model.DevFileType{}, err
}
Expand All @@ -145,7 +145,7 @@ func selectDevfiles(path string, devFileTypesFromRegistry []model.DevFileType) (
}

func SelectDevFileFromRegistry(path string, url string) (model.DevFileType, error) {
devFileTypes, err := downloadDevFileTypesFromRegistry(url, model.DevfileFilter{MinSchemaVersion: "", MaxSchemaVersion: ""})
devFileTypes, err := DownloadDevFileTypesFromRegistry(url, model.DevfileFilter{MinSchemaVersion: "", MaxSchemaVersion: ""})
if err != nil {
return model.DevFileType{}, err
}
Expand Down Expand Up @@ -203,7 +203,7 @@ func GetUrlWithVersions(url, minSchemaVersion, maxSchemaVersion string) (string,
}
}

func downloadDevFileTypesFromRegistry(url string, filter model.DevfileFilter) ([]model.DevFileType, error) {
func DownloadDevFileTypesFromRegistry(url string, filter model.DevfileFilter) ([]model.DevFileType, error) {
url = adaptUrl(url)
tmpUrl := appendIndexPath(url)
url, err := GetUrlWithVersions(tmpUrl, filter.MinSchemaVersion, filter.MaxSchemaVersion)
Expand Down
27 changes: 27 additions & 0 deletions pkg/schema/devfile_yaml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc.
******************************************************************************/

package schema

type DevfileYaml struct {
StarterProjects []struct {
Git struct {
CheckoutFrom struct {
Remote string `yaml:"remote"`
Revision string `yaml:"revision"`
} `yaml:"checkoutFrom"`
Remotes struct {
Origin string `yaml:"origin"`
} `yaml:"remotes"`
} `yaml:"git"`
SubDir string `yaml:"subDir"`
} `yaml:"starterProjects"`
}
195 changes: 195 additions & 0 deletions test/check_registry/check_registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"

"github.com/devfile/alizer/pkg/apis/model"
recognizer "github.com/devfile/alizer/pkg/apis/recognizer"
"github.com/devfile/alizer/pkg/schema"
"gopkg.in/yaml.v2"
)

type StarterProject struct {
Repo string
SubDir string
Revision string
Remote string
}

type ProjectReplacement struct {
Devfile string
ReplacementRepo string
}

type RegistryCheckJSONItem struct {
Devfile string
Repo string
Revision string
Registry string
SubDir string
}

type DevfileRegistry struct {
Name string
Url string
Filter model.DevfileFilter
}

// getProjectReplacements: Returns any stacks that have different remotes and they cannot
// be found from the detection algorithm
func getProjectReplacements() []ProjectReplacement {
return []ProjectReplacement{
{
Devfile: "java-wildfly",
ReplacementRepo: "https://github.com/wildfly-extras/wildfly-devfile-examples.git",
},
{
Devfile: "java-quarkus",
ReplacementRepo: "https://github.com/devfile-samples/devfile-sample-code-with-quarkus",
},
{
Devfile: "java-jboss-eap-xp",
ReplacementRepo: "https://github.com/jboss-developer/jboss-eap-quickstarts",
},
{
Devfile: "java-jboss-eap-xp-bootable-jar",
ReplacementRepo: "https://github.com/jboss-developer/jboss-eap-quickstarts",
},
}
}

// getRegistries: Fetches all registries we want to run the check
func getRegistries() []DevfileRegistry {
return []DevfileRegistry{
{
Name: "Community Registry",
Url: "https://registry.devfile.io",
Filter: model.DevfileFilter{},
},
{
Name: "Product Registry",
Url: "https://devfile-registry.redhat.com",
Filter: model.DevfileFilter{},
},
}
}

// getExcludedEntries: Returns a list of excluded stacks from the check
func getExcludedEntries() []string {
return []string{}
}

func getStarterProjects(url string) ([]StarterProject, error) {
// This value is set by the user in order to configure the registry
var starterProjects []StarterProject
resp, err := http.Get(url) // #nosec G107
if err != nil {
return []StarterProject{}, err
}
defer func() error {
if err := resp.Body.Close(); err != nil {
return fmt.Errorf("error closing file: %s", err)
}
return nil
}()

// Check server response
if resp.StatusCode != http.StatusOK {

return []StarterProject{}, fmt.Errorf("unable to fetch starter project from registry %s. code: %d", url, resp.StatusCode)
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []StarterProject{}, fmt.Errorf("unable to read body from response - error: %s", err)
}

// For each devfile fetched from the list, get the information from the detail page
var devfileYaml schema.DevfileYaml
err = yaml.Unmarshal(body, &devfileYaml)
if err != nil {
return []StarterProject{}, fmt.Errorf("unable to unmarshal json from response - error: %s", err)
}

for _, starterProject := range devfileYaml.StarterProjects {
starterProjects = append(starterProjects, StarterProject{
Repo: starterProject.Git.Remotes.Origin,
SubDir: starterProject.SubDir,
Revision: starterProject.Git.CheckoutFrom.Revision,
Remote: starterProject.Git.CheckoutFrom.Remote,
})
}
return starterProjects, nil
}

func appendIfMissing(slice []RegistryCheckJSONItem, r RegistryCheckJSONItem) []RegistryCheckJSONItem {
for _, ele := range slice {
if ele == r {
return slice
}
}
return append(slice, r)
}

func isIgnoredEntry(name string) bool {
excludedEntries := getExcludedEntries()
for _, excludedEntry := range excludedEntries {
if excludedEntry == name {
return true
}
}
return false
}

func main() {
var registryEntriesList []RegistryCheckJSONItem
devfileRegistries := getRegistries()
projectReplacements := getProjectReplacements()

for _, registry := range devfileRegistries {
tmpDevfileTypes, err := recognizer.DownloadDevFileTypesFromRegistry(registry.Url, registry.Filter)
if err != nil {
continue
}
for _, devfileType := range tmpDevfileTypes {
// Continnue if the entry is inside the excluded list
if isIgnoredEntry(devfileType.Name) {
continue
}
// For every stack get its detailed devfile.yaml
starterProjects, err := getStarterProjects(fmt.Sprintf("%s/devfiles/%s", registry.Url, devfileType.Name))
if err != nil {
continue
}
if len(starterProjects) == 0 {
continue
}

starterProject := starterProjects[0]
repo := starterProject.Repo
if repo == "" {
for _, projectReplacement := range projectReplacements {
if devfileType.Name == projectReplacement.Devfile {
repo = projectReplacement.ReplacementRepo
}
}
}
registryEntryItem := RegistryCheckJSONItem{
Devfile: devfileType.Name,
Repo: repo,
Registry: registry.Url,
Revision: starterProject.Revision,
SubDir: starterProject.SubDir,
}
registryEntriesList = appendIfMissing(registryEntriesList, registryEntryItem)
}
jsonBytes, err := json.Marshal(registryEntriesList)
if err != nil {
return
}
fmt.Println(string(jsonBytes))
}
}
67 changes: 67 additions & 0 deletions test/check_registry/check_registry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash

# Fetch all entries from registries
echo ":: Creating Registry Entries JSON..."
echo ""
echo ""
REGISTRY_ENTRIES_OUTPUT=$(go run test/check_registry/check_registry.go)
ENTRIES_PASSED=0
ENTRIES_FAILED=0

for entry in $(echo $REGISTRY_ENTRIES_OUTPUT | jq -c '.[]')
do
# Assign variables for this entry
devfile=$(jq -r '.Devfile' <<< $entry)
path="tmp/$devfile"
found_matching=1
repo=$(jq -r '.Repo' <<< $entry)
registry=$(jq -r '.Registry' <<< $entry)
revision=$(jq -r '.Revision' <<< $entry)
subdir=$(jq -r '.SubDir' <<< $entry)

# Clone project according to data
echo ":: Cloning project for entry <$devfile>"
echo ""
echo ""

if [ "$revision" != "" ]; then
echo "$devfile -> found revision $revision for repo $repo"
git clone --single-branch --branch $revision $repo tmp/$devfile
else
git clone $repo tmp/$devfile
fi

if [ "$subdir" != "" ]; then
path="$path/$subdir"
fi

# Checking with alizer
echo ""
echo ""
echo ":: Running alizer against path $path"
echo ""
echo ""
alizer_output=$(./alizer devfile --registry $registry $path)
for raw_selected_devfile_name in $(echo $alizer_output | jq -c '.[].Name')
do
selected_devfile_name=$(sed -e 's/^"//' -e 's/"$//' <<<"$raw_selected_devfile_name")
# Loop through the list of proposed devfiles to find the correct one
if [[ "$selected_devfile_name" == *"$devfile"* ]]; then
# If devfile name is contained inside selected one success
echo "------------------"
echo "SUCCESS - Devfile Name: $devfile <> Matched Devfile Name: $selected_devfile_name"
echo "------------------"
echo ""
let ENTRIES_PASSED++
found_matching=1
fi
# If the correct devfile is not matched throw error
if [ "$found_matching" == "0" ]; then
let ENTRIES_FAILED++
echo "[FAIL] Project $repo matched with $selected_devfile_name name. Expected $devfile (PASSED: $ENTRIES_PASSED / FAILED: $ENTRIES_FAILED)"
exit 1
fi
done
rm -rf tmp/$devfile
done
echo "[OK] PASSED: $ENTRIES_PASSED / FAILED: $ENTRIES_FAILED"

0 comments on commit aca6e69

Please sign in to comment.