As part of fixing failing third-party tests, this PR significantly rearchitects their specification and execution. Third-party tests are now specified in a much more flexible format allowing more customization on a per-package level. In addition, third-party tests are now used to auto-generate a Github Actions workflow to perform the tests in parallel. This not only gives faster feedback on PRs, but will also allow us to more quickly narrow down on which packages are failing. An additional workflow also confirms that local execution of third-party tests is consistent with the Github Actions version. This workflow only runs when tests/thirdparty itself is changed.
149 lines
3.0 KiB
Go
149 lines
3.0 KiB
Go
//go:build ignore
|
|
// +build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"runtime"
|
|
|
|
"github.com/mmcloughlin/avo/internal/prnt"
|
|
"github.com/mmcloughlin/avo/tests/thirdparty"
|
|
)
|
|
|
|
var (
|
|
pkgsfilename = flag.String("pkgs", "", "packages configuration")
|
|
output = flag.String("output", "", "path to output file (default stdout)")
|
|
)
|
|
|
|
func main() {
|
|
if err := mainerr(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func mainerr() error {
|
|
flag.Parse()
|
|
|
|
// Read packages.
|
|
pkgs, err := thirdparty.LoadPackagesFile(*pkgsfilename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := pkgs.Validate(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Determine output.
|
|
w := os.Stdout
|
|
if *output != "" {
|
|
f, err := os.Create(*output)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
w = f
|
|
}
|
|
|
|
// Generate workflow file.
|
|
b, err := GenerateWorkflow(pkgs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Write output.
|
|
if _, err := w.Write(b); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GenerateWorkflow(pkgs thirdparty.Packages) ([]byte, error) {
|
|
g := &prnt.Generator{}
|
|
g.SetIndentString(" ")
|
|
|
|
_, self, _, _ := runtime.Caller(0)
|
|
g.Linef("# Code generated by %s. DO NOT EDIT.", filepath.Base(self))
|
|
g.NL()
|
|
|
|
// Header.
|
|
g.Linef("name: packages")
|
|
|
|
g.Linef("permissions:")
|
|
g.Linef(" contents: read")
|
|
|
|
g.Linef("on:")
|
|
g.Linef(" push:")
|
|
g.Linef(" branches:")
|
|
g.Linef(" - master")
|
|
g.Linef(" pull_request:")
|
|
|
|
// One job per package.
|
|
g.NL()
|
|
g.Linef("jobs:")
|
|
g.Indent()
|
|
for _, pkg := range pkgs {
|
|
g.Linef("%s:", pkg.ID())
|
|
g.Indent()
|
|
|
|
g.Linef("runs-on: ubuntu-latest")
|
|
g.Linef("steps:")
|
|
g.Indent()
|
|
|
|
// Install Go.
|
|
g.Linef("- name: Install Go")
|
|
g.Linef(" uses: actions/setup-go@37335c7bb261b353407cff977110895fa0b4f7d8 # v2.1.3")
|
|
g.Linef(" with:")
|
|
g.Linef(" go-version: 1.17.x")
|
|
|
|
// Checkout avo.
|
|
avodir := "avo"
|
|
g.Linef("- name: Checkout avo")
|
|
g.Linef(" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4")
|
|
g.Linef(" with:")
|
|
g.Linef(" path: %s", avodir)
|
|
g.Linef(" persist-credentials: false")
|
|
|
|
// Checkout the third-party package.
|
|
pkgdir := pkg.Repository.Name
|
|
g.Linef("- name: Checkout %s", pkg.Repository)
|
|
g.Linef(" uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4")
|
|
g.Linef(" with:")
|
|
g.Linef(" repository: %s", pkg.Repository)
|
|
g.Linef(" ref: %s", pkg.Version)
|
|
g.Linef(" path: %s", pkgdir)
|
|
g.Linef(" persist-credentials: false")
|
|
|
|
// Build steps.
|
|
c := &thirdparty.Context{
|
|
AvoDirectory: path.Join("${{ github.workspace }}", avodir),
|
|
RepositoryDirectory: path.Join("${{ github.workspace }}", pkgdir),
|
|
}
|
|
|
|
for _, step := range pkg.Steps(c) {
|
|
g.Linef("- name: %s", step.Name)
|
|
g.Linef(" working-directory: %s", path.Join(pkgdir, step.WorkingDirectory))
|
|
if len(step.Commands) == 1 {
|
|
g.Linef(" run: %s", step.Commands[0])
|
|
} else {
|
|
g.Linef(" run: |")
|
|
for _, cmd := range step.Commands {
|
|
g.Linef(" %s", cmd)
|
|
}
|
|
}
|
|
}
|
|
|
|
g.Dedent()
|
|
g.Dedent()
|
|
}
|
|
g.Dedent()
|
|
|
|
return g.Result()
|
|
}
|