diff --git a/.github/workflows/test_package.yml b/.github/workflows/test_package.yml new file mode 100644 index 0000000000..1a3698c493 --- /dev/null +++ b/.github/workflows/test_package.yml @@ -0,0 +1,59 @@ +name: Package tests + +on: + push: + branches: + - cluster + - master + paths: + - '.github/workflows/test_package.yml' + - '**/Dockerfile*' + - '**/Makefile' + pull_request: + branches: + - cluster + - master + paths: + - '.github/workflows/test_package.yml' + - '**/Dockerfile*' + - '**/Makefile' + +permissions: + contents: read + +concurrency: + cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + +jobs: + test_release: + name: Test Release + runs-on: ubuntu-latest + steps: + - name: Code checkout + uses: actions/checkout@v4 + + - name: Setup Go + id: go + uses: actions/setup-go@v5 + with: + go-version: stable + cache: false + + - name: Cache Go artifacts + uses: actions/cache@v4 + with: + path: | + ~/.cache/go-build + ~/go/bin + ~/go/pkg/mod + key: go-artifacts-${{ runner.os }}-test-release-${{ steps.go.outputs.go-version }}-${{ hashFiles('Makefile', '**/Dockerfile*', '**/Makefile') }} + restore-keys: go-artifacts-${{ runner.os }}-test-release- + + - name: Run make release + run: | + make clean + make release + + - name: Run release tests + run: make test-release-victoria-metrics diff --git a/package/release/Makefile b/package/release/Makefile index 2a185b9f43..3f34250ad8 100644 --- a/package/release/Makefile +++ b/package/release/Makefile @@ -69,3 +69,6 @@ github-delete-release: github-token-check cat $(GITHUB_DEBUG_FILE); \ exit 1; \ fi + +test-release-victoria-metrics: + @go test -run TestVictoriaMetrics package/release/asset_test.go diff --git a/package/release/asset_test.go b/package/release/asset_test.go new file mode 100644 index 0000000000..c6540822fd --- /dev/null +++ b/package/release/asset_test.go @@ -0,0 +1,117 @@ +package main + +import ( + "crypto/sha1" + "fmt" + "io" + "io/fs" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func execCommand(command string) *exec.Cmd { + cmd := strings.Fields(command) + return exec.Command(cmd[0], cmd[1:]...) +} + +func getArchOsMap() map[string][]string { + return map[string][]string{ + "darwin": {"amd64", "arm64"}, + "freebsd": {"amd64"}, + "linux": {"386", "amd64", "arm", "arm64"}, + "openbsd": {"amd64"}, + "windows": {"amd64"}, + } +} + +func getFileInfo(filePath string) (fs.FileInfo, error) { + fileInfo, err := os.Stat(filePath) + if err != nil { + return fileInfo, err + } + + return fileInfo, nil +} + +func getParentDirectory(path string, directoriesUp int) string { + for i := 0; i < directoriesUp; i++ { + path = filepath.Dir(path) + } + return path +} + +func getTag() (string, error) { + stdOut, err := execCommand("git describe --long --all").Output() + + if err != nil { + fmt.Println(err) + return "", err + } + tag := strings.ReplaceAll(strings.ReplaceAll(string(stdOut), "/", "-"), "\n", "") + + // Check if there is a difference with the HEAD. + gitDiff := execCommand("git diff-index --quiet HEAD --") + err = gitDiff.Run() + if _, ok := err.(*exec.ExitError); ok { + gitDiffStdOut, _ := execCommand("git diff-index -u HEAD").Output() + hashGenerator := sha1.New() + io.WriteString(hashGenerator, string(gitDiffStdOut)) + sha1Hex := fmt.Sprintf("%x", hashGenerator.Sum(nil)[0:4]) + tag = strings.Join([]string{tag, "-dirty-", sha1Hex}, "") + } + + return tag, nil +} + +func testComponentAssets(t *testing.T, componentNames []string) { + tag, err := getTag() + if err != nil { + t.Fatalf("Unable to get a tag: %v", err) + } + + cwd, err := os.Getwd() + if err != nil { + t.Fatalf("Unable to get CWD: %v", err) + } + + binPath := filepath.Join(getParentDirectory(cwd, 2), "bin") + + for _, componentName := range componentNames { + for osName, archNames := range getArchOsMap() { + for _, archName := range archNames { + fileExtension := ".tar.gz" + if osName == "windows" { + fileExtension = ".zip" + } + fileNamePrefix := strings.Join([]string{componentName, osName, archName, tag}, "-") + + // Check archive file. + archiveFileName := strings.Join([]string{fileNamePrefix, fileExtension}, "") + archiveFilePath := filepath.Join(binPath, archiveFileName) + archiveFileInfo, err := getFileInfo(archiveFilePath) + if err != nil { + t.Errorf("Could not get archive file information: %s", archiveFilePath) + } else if archiveFileInfo.Size() == 0 { + t.Errorf("Archive file is empty: %s", archiveFilePath) + } + + // Check checksums file. + checksumsFileName := strings.Join([]string{fileNamePrefix, "_checksums.txt"}, "") + checksumsFilePath := filepath.Join(binPath, checksumsFileName) + checksumsFileInfo, err := getFileInfo(checksumsFilePath) + if err != nil { + t.Errorf("Could not get checksums file information: %s", checksumsFilePath) + } else if checksumsFileInfo.Size() == 0 { + t.Errorf("Checksums file is empty: %s", checksumsFilePath) + } + } + } + } +} + +func TestVictoriaMetrics(t *testing.T) { + testComponentAssets(t, []string{"victoria-metrics", "vmutils"}) +}