Skip to content

Commit 4d2ba88

Browse files
committed
internal/e2e: add a test for a private github repo
Since the GitHub App setup with registry.cue.works only knows how to publish module versions in a public way, any git tag created on a private github repo with the app installed does not get published as a module version in the registry. Tweaked our builtins so we can set the Repo.Private field as well as allowing negating and configuring the timeout in cue-mod-wait. Signed-off-by: Daniel Martí <[email protected]> Change-Id: Ide73065b6aeebfaefb5d464a8e446c54a14410fe Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1171965 Reviewed-by: Roger Peppe <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent 95a88a5 commit 4d2ba88

File tree

2 files changed

+94
-7
lines changed

2 files changed

+94
-7
lines changed

internal/e2e/script_test.go

+37-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"os"
2323
"os/exec"
2424
"path/filepath"
25+
"strconv"
2526
"strings"
2627
"testing"
2728
"time"
@@ -101,8 +102,8 @@ func TestScript(t *testing.T) {
101102
// create-github-repo creates a unique repository under githubOrg
102103
// and sets $MODULE to its resulting module path.
103104
"create-github-repo": func(ts *testscript.TestScript, neg bool, args []string) {
104-
if neg || len(args) > 0 {
105-
ts.Fatalf("usage: create-github-repo")
105+
if neg {
106+
ts.Fatalf("usage: create-github-repo [field=value...]")
106107
}
107108

108109
// githubToken should have read and write access to repository
@@ -118,6 +119,20 @@ func TestScript(t *testing.T) {
118119
repo := &github.Repository{
119120
Name: github.String(repoName),
120121
}
122+
for _, arg := range args {
123+
field, value, ok := strings.Cut(arg, "=")
124+
if !ok {
125+
ts.Fatalf("invalid field=value arg: %q", arg)
126+
}
127+
switch field {
128+
case "private":
129+
b, err := strconv.ParseBool(value)
130+
ts.Check(err)
131+
repo.Private = addr(b)
132+
default:
133+
ts.Fatalf("unsupported field: %q", field)
134+
}
135+
}
121136
_, _, err := client.Repositories.Create(ctx, githubOrg, repo)
122137
ts.Check(err)
123138

@@ -133,8 +148,10 @@ func TestScript(t *testing.T) {
133148
ts.Check(err)
134149
})
135150

136-
ts.Setenv("MODULE", fmt.Sprintf("github.com/%s/%s", githubOrg, repoName))
151+
module := fmt.Sprintf("github.com/%s/%s", githubOrg, repoName)
152+
ts.Setenv("MODULE", module)
137153
ts.Setenv("GITHUB_TOKEN", githubToken) // needed for "git push"
154+
ts.Logf("created github repo: https://%s", module)
138155
},
139156
// env-fill rewrites its argument files to replace any environment variable
140157
// references with their values, using the same algorithm as cmpenv.
@@ -152,23 +169,34 @@ func TestScript(t *testing.T) {
152169
// cue-mod-wait waits for a CUE module to exist in a registry for up to 20s.
153170
// Since this is easily done via an HTTP HEAD request, an OCI client isn't necessary.
154171
"cue-mod-wait": func(ts *testscript.TestScript, neg bool, args []string) {
155-
if neg || len(args) > 0 {
156-
ts.Fatalf("usage: cue-mod-wait")
172+
if len(args) > 1 {
173+
ts.Fatalf("usage: [!] cue-mod-wait [timeout]")
157174
}
158175
manifest := tsExpand(ts, "https://${CUE_REGISTRY}/v2/${MODULE}/manifests/${VERSION}")
176+
timeout := 20 * time.Second
177+
if len(args) > 0 {
178+
var err error
179+
timeout, err = time.ParseDuration(args[0])
180+
ts.Check(err)
181+
}
159182
retries := retry.Strategy{
160183
Delay: 10 * time.Millisecond,
161184
MaxDelay: time.Second,
162-
MaxDuration: 20 * time.Second,
185+
MaxDuration: timeout,
163186
}
164187
for it := retries.Start(); it.Next(nil); {
165188
resp, err := http.Head(manifest)
166189
ts.Check(err)
167190
if resp.StatusCode == http.StatusOK {
191+
if neg {
192+
ts.Fatalf("%s was unexpectedly published", manifest)
193+
}
168194
return
169195
}
170196
}
171-
ts.Fatalf("timed out waiting for module")
197+
if !neg {
198+
ts.Fatalf("timed out waiting for %s", manifest)
199+
}
172200
},
173201
// gcloud-auth-docker configures gcloud so that it uses the host's existing configuration,
174202
// and sets CUE_REGISTRY and CUE_REGISTRY_HOST according to gcloudRegistry.
@@ -200,6 +228,8 @@ func TestScript(t *testing.T) {
200228
testscript.Run(t, p)
201229
}
202230

231+
func addr[T any](t T) *T { return &t }
232+
203233
func envOr(name, fallback string) string {
204234
if s := os.Getenv(name); s != "" {
205235
return s
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Create a private GitHub repository in an org with the GitHub App
2+
# "CUE Module Publisher" installed for all repositories.
3+
# Push a git tag with a simple CUE module, and check that the app
4+
# does not publish a version that is publicly accessible.
5+
6+
create-github-repo private=true
7+
env VERSION=v0.0.1
8+
env MODVER=${MODULE}@v0
9+
10+
cd publish
11+
12+
# TODO: replace by "cue mod init" once it supports versioned module names.
13+
# cue mod init ${MODVER}
14+
env-fill cue.mod/module.cue
15+
16+
exec git init --initial-branch main
17+
exec git config user.name 'modules_e2e'
18+
exec git config user.email 'modules_e2e@bot'
19+
exec git remote add origin https://${GITHUB_TOKEN}@${MODULE}
20+
21+
exec git add foo.cue cue.mod
22+
exec git commit -m 'first commit'
23+
exec git tag cue-${VERSION}
24+
25+
exec git push origin main cue-${VERSION}
26+
27+
# The app publishing method gives no feedback right now,
28+
# so we instead check that the module version isn't published on the registry within a timeout.
29+
# From previous test runs, it takes between 5 and 8 seconds between pushing a git tag
30+
# on a public repo and the module version being published on the registry,
31+
# so 20 seconds is likely more than enough here to ensure it won't be published.
32+
! cue-mod-wait 20s
33+
34+
cd ../depend
35+
36+
# Double check that cmd/cue cannot download the dependency either.
37+
env-fill cue.mod/module.cue out_foo.cue
38+
! exec cue export
39+
stderr 'cannot resolve dependencies'
40+
41+
-- publish/cue.mod/module.cue --
42+
module: "${MODVER}"
43+
-- publish/foo.cue --
44+
package publish
45+
46+
foo: "foo value"
47+
48+
-- depend/cue.mod/module.cue --
49+
module: "depend.localhost"
50+
51+
deps: "${MODVER}": v: "${VERSION}"
52+
-- depend/out_foo.cue --
53+
package depend
54+
55+
import mt "${MODVER}:publish"
56+
57+
out: mt.foo

0 commit comments

Comments
 (0)