cuelang.org/go@v0.10.1/internal/ci/github/trybot.cue (about)

     1  // Copyright 2022 The CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package github
    16  
    17  import (
    18  	"list"
    19  
    20  	"github.com/SchemaStore/schemastore/src/schemas/json"
    21  )
    22  
    23  // The trybot workflow.
    24  workflows: trybot: _repo.bashWorkflow & {
    25  	name: _repo.trybot.name
    26  
    27  	on: {
    28  		push: {
    29  			branches: list.Concat([[_repo.testDefaultBranch], _repo.protectedBranchPatterns]) // do not run PR branches
    30  			"tags-ignore": [_repo.releaseTagPattern]
    31  		}
    32  		pull_request: {}
    33  	}
    34  
    35  	jobs: {
    36  		test: {
    37  			strategy:  _testStrategy
    38  			"runs-on": "${{ matrix.runner }}"
    39  
    40  			let _setupGoActionsCaches = _repo.setupGoActionsCaches & {
    41  				#goVersion: goVersionVal
    42  				#os:        runnerOSVal
    43  				_
    44  			}
    45  
    46  			// Only run the trybot workflow if we have the trybot trailer, or
    47  			// if we have no special trailers. Note this condition applies
    48  			// after and in addition to the "on" condition above.
    49  			if: "\(_repo.containsTrybotTrailer) || ! \(_repo.containsDispatchTrailer)"
    50  
    51  			steps: [
    52  				for v in _repo.checkoutCode {v},
    53  
    54  				_repo.installGo & {
    55  					with: "go-version": goVersionVal
    56  				},
    57  
    58  				// cachePre must come after installing Node and Go, because the cache locations
    59  				// are established by running each tool.
    60  				for v in _setupGoActionsCaches {v},
    61  
    62  				_repo.earlyChecks & {
    63  					// These checks don't vary based on the Go version or OS,
    64  					// so we only need to run them on one of the matrix jobs.
    65  					if: _isLatestLinux
    66  				},
    67  				_goGenerate,
    68  				_goTest & {
    69  					if: "\(_repo.isProtectedBranch) || !\(_isLatestLinux)"
    70  				},
    71  				_goTestRace & {
    72  					if: _isLatestLinux
    73  				},
    74  				_goTestWasm,
    75  				for v in _e2eTestSteps {v},
    76  				_goCheck,
    77  				_repo.checkGitClean,
    78  			]
    79  		}
    80  	}
    81  
    82  	let runnerOS = "runner.os"
    83  	let runnerOSVal = "${{ \(runnerOS) }}"
    84  	let matrixRunner = "matrix.runner"
    85  	let goVersion = "matrix.go-version"
    86  	let goVersionVal = "${{ \(goVersion) }}"
    87  
    88  	_testStrategy: {
    89  		"fail-fast": false
    90  		matrix: {
    91  			"go-version": _repo.matrixGo
    92  			runner: [_repo.linuxMachine, _repo.macosMachine, _repo.windowsMachine]
    93  		}
    94  	}
    95  
    96  	// _isLatestLinux returns a GitHub expression that evaluates to true if the job
    97  	// is running on Linux with the latest version of Go. This expression is often
    98  	// used to run certain steps just once per CI workflow, to avoid duplicated
    99  	// work.
   100  	_isLatestLinux: "(\(goVersion) == '\(_repo.latestGo)' && \(matrixRunner) == '\(_repo.linuxMachine)')"
   101  
   102  	_goGenerate: json.#step & {
   103  		name: "Generate"
   104  		run:  "go generate ./..."
   105  		// The Go version corresponds to the precise version specified in
   106  		// the matrix. Skip windows for now until we work out why re-gen is flaky
   107  		if: _isLatestLinux
   108  	}
   109  
   110  	_goTest: json.#step & {
   111  		name: "Test"
   112  		run:  "go test ./..."
   113  	}
   114  
   115  	_e2eTestSteps: [... json.#step & {
   116  		// The end-to-end tests require a github token secret and are a bit slow,
   117  		// so we only run them on pushes to protected branches and on one
   118  		// environment in the source repo.
   119  		if: "github.repository == '\(_repo.githubRepositoryPath)' && (\(_repo.isProtectedBranch) || \(_repo.isTestDefaultBranch)) && \(_isLatestLinux)"
   120  	}] & [
   121  		// Two setup steps per the upstream docs:
   122  		// https://github.com/google-github-actions/setup-gcloud#service-account-key-json
   123  		{
   124  			name: "gcloud auth for end-to-end tests"
   125  			id:   "auth"
   126  			uses: "google-github-actions/auth@v2"
   127  			// E2E_GCLOUD_KEY is a key for the service account cue-e2e-ci,
   128  			// which has the Artifact Registry Repository Administrator role.
   129  			with: credentials_json: "${{ secrets.E2E_GCLOUD_KEY }}"
   130  		},
   131  		{
   132  			name: "gcloud setup for end-to-end tests"
   133  			uses: "google-github-actions/setup-gcloud@v2"
   134  		},
   135  		{
   136  			name: "End-to-end test"
   137  			// The secret is the fine-grained access token "cue-lang/cue ci e2e for modules-testing"
   138  			// owned by the porcuepine bot account with read+write access to repo administration and code
   139  			// on the entire cue-labs-modules-testing org. Note that porcuepine is also an org admin,
   140  			// since otherwise the repo admin access to create and delete repos does not work.
   141  			env: {
   142  				CUE_TEST_LOGINS: "${{ secrets.E2E_CUE_LOGINS }}"
   143  			}
   144  			// Our regular tests run with both `go test ./...` and `go test -race ./...`.
   145  			// The end-to-end tests should only be run once, given the slowness and API rate limits.
   146  			// We want to catch any data races they spot as soon as possible, and they aren't CPU-bound,
   147  			// so running them only with -race seems reasonable.
   148  			run: """
   149  				cd internal/_e2e
   150  				go test -race
   151  				"""
   152  		},
   153  	]
   154  
   155  	_goCheck: json.#step & {
   156  		// These checks can vary between platforms, as different code can be built
   157  		// based on GOOS and GOARCH build tags.
   158  		// However, CUE does not have any such build tags yet, and we don't use
   159  		// dependencies that vary wildly between platforms.
   160  		// For now, to save CI resources, just run the checks on one matrix job.
   161  		//
   162  		// Also ensure that the end-to-end tests in ./internal/_e2e, which are only run
   163  		// on pushes to protected branches, still build correctly before merging.
   164  		//
   165  		// TODO: consider adding more checks as per https://github.com/golang/go/issues/42119.
   166  		if:   "\(_isLatestLinux)"
   167  		name: "Check"
   168  		run: """
   169  			go vet ./...
   170  			go mod tidy
   171  			(cd internal/_e2e && go test -run=-)
   172  			"""
   173  	}
   174  
   175  	_goTestRace: json.#step & {
   176  		name: "Test with -race"
   177  		env: GORACE: "atexit_sleep_ms=10" // Otherwise every Go package being tested sleeps for 1s; see https://go.dev/issues/20364.
   178  		run: "go test -race ./..."
   179  	}
   180  
   181  	_goTestWasm: json.#step & {
   182  		name: "Test with -tags=cuewasm"
   183  		// The wasm interpreter is only bundled into cmd/cue with the cuewasm build tag.
   184  		// Test the related packages with the build tag enabled as well.
   185  		run: "go test -tags cuewasm ./cmd/cue/cmd ./cue/interpreter/wasm"
   186  	}
   187  }