1// Copyright 2021 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
15package base
16
17import (
18 "path"
19 "encoding/json"
20 "tool/file"
21 "tool/exec"
22
23 "cue.dev/x/githubactions"
24)
25
26// For the commands below, note we use simple yet hacky path resolution, rather
27// than anything that might derive the module root using go list or similar, in
28// order that we have zero dependencies. This is important because this CUE
29// package is "vendored" to an external dependency so that that unity can
30// re-run and verify these steps as part of the test suite that runs against
31// new CUE versions.
32
33// TODO(mvdan): without the default, this doesn't seem to be filled by
34// `cue cmd gen` in internal/ci, even though the command defaults --inject-vars to true.
35// Perhaps it doesn't work for imported packages? It seems to me like it should.
36_goos: string | *path.Unix @tag(os,var=os)
37
38// uniqueWorkflowNames enforces that workflow names are unique,
39// since we use them to uniquely identify workflow runs depicted in GitHub events,
40// such as "TryBot" or "Unity".
41uniqueWorkflowNames: self={
42 _uniqueWorkflowNames: {
43 for basename, workflow in self {
44 (workflow.name): basename
45 }
46 }
47}
48
49// writefs describes the input expected by `cue exp writefs`.
50#writefs: {
51 // tool is the name of the tool that initiated the writefs call.
52 tool!: string
53
54 // remove is a list of glob patterns of files to remove before creating new ones.
55 remove?: [...string]
56
57 // create is the set of files to create, keyed by Unix file paths.
58 create?: [filepath=string]: {
59 type!: "symlink"
60 contents!: string
61 } | *{
62 // Note that this is a regular field so that it can be omitted as the default.
63 // Ideally we wouldn't mix defaults into a schema, but this is nice UX,
64 // and this carries forward the semantics we've had in a few repos for a while.
65 type: "file"
66
67 // If filepath has a supported file extension, such as .yaml or .json,
68 // this is an arbitrary concrete value written in that encoding.
69 // Otherwise, this is a string written as-is.
70 contents!: _
71 }
72}
73
74// writeWorkflows regenerates the GitHub workflow YAML definitions.
75writeWorkflows: {
76 #in: {
77 workflows: [string]: githubactions.#Workflow
78 workflows: uniqueWorkflowNames
79 }
80 _dir: path.FromSlash("../../.github/workflows", path.Unix)
81
82 gen: exec.Run & {
83 cmd: ["go", "tool", "cue", "exp", "writefs"]
84 stdin: json.Marshal(#writefs & {
85 tool: "internal/ci/base/write.cue"
86 remove: [path.Join([_dir, "*" + workflowFileExtension], _goos)]
87 create: {
88 for _workflowName, _workflow in #in.workflows {
89 let filepath = path.Join([_dir, _workflowName + workflowFileExtension], _goos)
90 (filepath): contents: _workflow
91 }
92 }
93 })
94 }
95}
96
97writeCodereviewCfg: file.Create & {
98 _dir: path.FromSlash("../../", path.Unix)
99 filename: path.Join([_dir, "codereview.cfg"], _goos)
100 let res = toCodeReviewCfg & {#input: codeReview, _}
101 let donotedit = doNotEditMessage & {#generatedBy: "internal/ci/base/write.cue", _}
102 contents: "# \(donotedit)\n\n\(res)\n"
103}