Merge branch 'trunk' into verify-provenance-predicate-by-default
This commit is contained in:
commit
c552224081
13 changed files with 197 additions and 17 deletions
|
|
@ -159,7 +159,9 @@ When tests fail they fail like this:
|
|||
This is generally enough information to understand why a test has failed. However, we can get more information by providing the `-v` flag to `go test`, which turns on verbose mode and shows each command and any associated `stdio`.
|
||||
|
||||
> [!WARNING]
|
||||
> Verbose mode dumps the `testscript` environment variables, including the `GH_TOKEN`, so be careful.
|
||||
> Verbose mode dumps the `testscript` environment variables, so make sure there is nothing sensitive in there.
|
||||
> We have taken steps to [redact tokens](https://github.com/cli/cli/pull/9804) in log output but there's no
|
||||
> guarantee it's comprehensive.
|
||||
|
||||
By default `testscript` removes the directory in which it was running the script, and if you've been a conscientious engineer, you should be cleaning up resources using the `defer` statement. However, this can be an impediment to debugging. As such you can set `GH_ACCEPTANCE_PRESERVE_WORK_DIR=true` and `GH_ACCEPTANCE_SKIP_DEFER=true` to skip these cleanup steps.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/cli/cli/v2/internal/ghcmd"
|
||||
"github.com/rogpeppe/go-internal/testscript"
|
||||
"github.com/cli/go-internal/testscript"
|
||||
)
|
||||
|
||||
func ghMain() int {
|
||||
|
|
@ -63,6 +63,15 @@ func TestAPI(t *testing.T) {
|
|||
testscript.Run(t, testScriptParamsFor(tsEnv, "api"))
|
||||
}
|
||||
|
||||
func TestAuth(t *testing.T) {
|
||||
var tsEnv testScriptEnv
|
||||
if err := tsEnv.fromEnv(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testscript.Run(t, testScriptParamsFor(tsEnv, "auth"))
|
||||
}
|
||||
|
||||
func TestReleases(t *testing.T) {
|
||||
var tsEnv testScriptEnv
|
||||
if err := tsEnv.fromEnv(); err != nil {
|
||||
|
|
@ -86,7 +95,7 @@ func TestRepo(t *testing.T) {
|
|||
if err := tsEnv.fromEnv(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
testscript.Run(t, testScriptParamsFor(tsEnv, "repo"))
|
||||
}
|
||||
|
||||
|
|
@ -108,6 +117,42 @@ func TestVariables(t *testing.T) {
|
|||
testscript.Run(t, testScriptParamsFor(tsEnv, "variable"))
|
||||
}
|
||||
|
||||
func TestGPGKeys(t *testing.T) {
|
||||
var tsEnv testScriptEnv
|
||||
if err := tsEnv.fromEnv(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testscript.Run(t, testScriptParamsFor(tsEnv, "gpg-key"))
|
||||
}
|
||||
|
||||
func TestLabels(t *testing.T) {
|
||||
var tsEnv testScriptEnv
|
||||
if err := tsEnv.fromEnv(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testscript.Run(t, testScriptParamsFor(tsEnv, "label"))
|
||||
}
|
||||
|
||||
func TestSSHKeys(t *testing.T) {
|
||||
var tsEnv testScriptEnv
|
||||
if err := tsEnv.fromEnv(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testscript.Run(t, testScriptParamsFor(tsEnv, "ssh-key"))
|
||||
}
|
||||
|
||||
func TestOrg(t *testing.T) {
|
||||
var tsEnv testScriptEnv
|
||||
if err := tsEnv.fromEnv(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testscript.Run(t, testScriptParamsFor(tsEnv, "org"))
|
||||
}
|
||||
|
||||
func testScriptParamsFor(tsEnv testScriptEnv, command string) testscript.Params {
|
||||
var files []string
|
||||
if tsEnv.script != "" {
|
||||
|
|
|
|||
25
acceptance/testdata/auth/auth-login-logout.txtar
vendored
Normal file
25
acceptance/testdata/auth/auth-login-logout.txtar
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# We aren't logged in at the moment, but GH_TOKEN will override the
|
||||
# need to login. We are going to clear GH_TOKEN first to ensure no
|
||||
# overrides are happening
|
||||
|
||||
# Copy $GH_TOKEN to a new env var
|
||||
env LOGIN_TOKEN=$GH_TOKEN
|
||||
|
||||
# Remove GH_TOKEN env var so we don't fall back to it
|
||||
env GH_TOKEN=''
|
||||
|
||||
# Login to the host by feeding the token to stdin
|
||||
exec echo $LOGIN_TOKEN
|
||||
stdin stdout
|
||||
exec gh auth login --hostname=$GH_HOST --with-token --insecure-storage
|
||||
|
||||
# Check that we are logged in
|
||||
exec gh auth status --hostname $GH_HOST
|
||||
stdout $GH_HOST
|
||||
|
||||
# Logout of the host
|
||||
exec gh auth logout --hostname $GH_HOST
|
||||
stderr 'Logged out of'
|
||||
|
||||
# Check that we are logged out
|
||||
! exec gh auth status --hostname $GH_HOST
|
||||
10
acceptance/testdata/auth/auth-setup-git.txtar
vendored
Normal file
10
acceptance/testdata/auth/auth-setup-git.txtar
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Check that the credential helper is unset for the host. This command is
|
||||
# expected to fail before gh auth setup-git is run.
|
||||
! exec git config --get credential.https://${GH_HOST}.helper
|
||||
|
||||
# Run the setup-git command
|
||||
exec gh auth setup-git
|
||||
|
||||
# Check that the credential helper is set to gh
|
||||
exec git config --get credential.https://${GH_HOST}.helper
|
||||
stdout '^.*gh auth git-credential$'
|
||||
3
acceptance/testdata/auth/auth-status.txtar
vendored
Normal file
3
acceptance/testdata/auth/auth-status.txtar
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Check the authentication status
|
||||
exec gh auth status --hostname $GH_HOST
|
||||
stdout '✓ Logged in to '
|
||||
3
acceptance/testdata/auth/auth-token.txtar
vendored
Normal file
3
acceptance/testdata/auth/auth-token.txtar
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Check authentication token
|
||||
exec gh auth token --hostname $GH_HOST
|
||||
stdout $GH_TOKEN
|
||||
36
acceptance/testdata/gpg-key/gpg-key.txtar
vendored
Normal file
36
acceptance/testdata/gpg-key/gpg-key.txtar
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
skip 'it modifies the user''s personal GitHub account GPG keys'
|
||||
|
||||
# This test requires the admin:gpg_key scope to add and delete GPG keys to and
|
||||
# from the user's personal GitHub account.
|
||||
# This test uses a GPG key that generated for this test only. The private key
|
||||
# has been deleted
|
||||
|
||||
# Add the gpg key to GH account
|
||||
exec gh gpg-key add gpg-key.pub
|
||||
|
||||
# Verify the gpg key was added to GH account
|
||||
exec gh gpg-key list
|
||||
stdout '24C30F9C9115E747'
|
||||
|
||||
# Delete the gpg key from GH account
|
||||
exec gh gpg-key delete --yes '24C30F9C9115E747'
|
||||
|
||||
# Check the key is deleted
|
||||
exec gh gpg-key list
|
||||
! stdout '24C30F9C9115E747'
|
||||
|
||||
-- gpg-key.pub --
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEZxpWhhYJKwYBBAHaRw8BAQdAmYiobR2ai/lVWOBtlAPRG1ZEMG5Effavpt5w
|
||||
n+wQ//W0R0dIIENMSSBhY2NlcHRhbmNlIHRlc3QgKGZvciBHSCBDTEkgYWNjZXB0
|
||||
YW5jZSB0ZXN0aW5nKSA8Y2xpQGdpdGh1Yi5jb20+iJkEExYKAEEWIQTEAQLLUl1x
|
||||
MDSmbL0kww+ckRXnRwUCZxpWhgIbAwUJAAFRgAULCQgHAgIiAgYVCgkICwIEFgID
|
||||
AQIeBwIXgAAKCRAkww+ckRXnRxkuAP9GiFi/etWxRjnkomdTaOU8Ccd6oHspuEzB
|
||||
PFxOJdYslQD+MXgY5UhM/q2iEVj0tiVsfRzDqB+g2weaF5EpqIwWcQ+4OARnGlaG
|
||||
EgorBgEEAZdVAQUBAQdA3D1vnVTc9URDQw/oAd1mG/zRX7vF4QrjFqFIt7uMf2gD
|
||||
AQgHiH4EGBYKACYWIQTEAQLLUl1xMDSmbL0kww+ckRXnRwUCZxpWhgIbDAUJAAFR
|
||||
gAAKCRAkww+ckRXnRxVuAQCngnR11jh2mob0FN0rPWce2juoJsh5gPB2d7LS4r5P
|
||||
VwEA6F2FeetcP51EyKyQGTp3GpmZgk0uCGJa1G5uqT+9mgc=
|
||||
=RLWi
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
25
acceptance/testdata/label/label.txtar
vendored
Normal file
25
acceptance/testdata/label/label.txtar
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Setup useful env vars
|
||||
env REPO=${SCRIPT_NAME}-${RANDOM_STRING}
|
||||
|
||||
# Create a repository
|
||||
exec gh repo create ${ORG}/${REPO} --private
|
||||
|
||||
# Defer repo cleanup
|
||||
defer gh repo delete --yes ${ORG}/${REPO}
|
||||
|
||||
# Set the GH_REPO env var to reduce redunant flags
|
||||
env GH_REPO=${ORG}/${REPO}
|
||||
|
||||
# Create a custom label
|
||||
exec gh label create 'acceptance-test' --description 'First Description'
|
||||
|
||||
# List the labels and check our custom label is there
|
||||
exec gh label list
|
||||
stdout 'acceptance-test\tFirst Description'
|
||||
|
||||
# Edit the label
|
||||
exec gh label edit 'acceptance-test' --description 'Edited Description'
|
||||
|
||||
# List the labels and check our custom label has been updated
|
||||
exec gh label list
|
||||
stdout 'acceptance-test\tEdited Description'
|
||||
6
acceptance/testdata/org/org-list.txtar
vendored
Normal file
6
acceptance/testdata/org/org-list.txtar
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# This test could fail if the user is a member of more than 30 organizations because
|
||||
# the `gh org list` command only returns the first 30 organizations the user is a member of
|
||||
|
||||
# List organizations the user is a member of
|
||||
exec gh org list
|
||||
stdout ${GH_ACCEPTANCE_ORG}
|
||||
24
acceptance/testdata/ssh-key/ssh-key.txtar
vendored
Normal file
24
acceptance/testdata/ssh-key/ssh-key.txtar
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
skip 'it modifies the user''s personal GitHub account SSH keys'
|
||||
|
||||
# scopes admin:ssh_signing_key,admin:public_key
|
||||
|
||||
# Add an SSH key to the account
|
||||
exec gh ssh-key add sshKey.pub --title 'acceptance-test-key'
|
||||
|
||||
# List the SSH keys
|
||||
exec gh ssh-key list
|
||||
stdout 'acceptance-test-key'
|
||||
|
||||
# Get the ID of the key we created
|
||||
exec gh api /user/keys --jq '.[] | select(.title == "acceptance-test-key") | .id'
|
||||
stdout2env SSH_KEY_ID
|
||||
|
||||
# Delete the SSH key
|
||||
exec gh ssh-key delete --yes ${SSH_KEY_ID}
|
||||
|
||||
# Check the key is deleted
|
||||
exec gh ssh-key list
|
||||
! stdout 'acceptance-test-key'
|
||||
|
||||
-- sshKey.pub --
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAZmdeRNskfpvYL5YHB/YJaW8hTEXpnvPMkx5Ri+YwUr acceptance
|
||||
4
go.mod
4
go.mod
|
|
@ -12,6 +12,7 @@ require (
|
|||
github.com/charmbracelet/glamour v0.7.0
|
||||
github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c
|
||||
github.com/cli/go-gh/v2 v2.11.0
|
||||
github.com/cli/go-internal v0.0.0-20241025142207-6c48bcd5ce24
|
||||
github.com/cli/oauth v1.1.1
|
||||
github.com/cli/safeexec v1.0.1
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5
|
||||
|
|
@ -125,7 +126,6 @@ require (
|
|||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rodaine/table v1.0.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.13.1
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
|
|
@ -167,5 +167,3 @@ require (
|
|||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
k8s.io/klog/v2 v2.120.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/rogpeppe/go-internal => github.com/cli/go-internal v0.0.0-20241024130215-fa3c22e38b9b
|
||||
|
|
|
|||
6
go.sum
6
go.sum
|
|
@ -97,8 +97,8 @@ github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
|
|||
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
|
||||
github.com/cli/go-gh/v2 v2.11.0 h1:TERLYMMWderKBO3lBff/JIu2+eSly2oFRgN2WvO+3eA=
|
||||
github.com/cli/go-gh/v2 v2.11.0/go.mod h1:MeRoKzXff3ygHu7zP+NVTT+imcHW6p3tpuxHAzRM2xE=
|
||||
github.com/cli/go-internal v0.0.0-20241024130215-fa3c22e38b9b h1:ogNz+pm9aI2Zn58V+WTMzPViN2fRVq/h2H9gwdvM09k=
|
||||
github.com/cli/go-internal v0.0.0-20241024130215-fa3c22e38b9b/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY=
|
||||
github.com/cli/go-internal v0.0.0-20241025142207-6c48bcd5ce24 h1:QDrhR4JA2n3ij9YQN0u5ZeuvRIIvsUGmf5yPlTS0w8E=
|
||||
github.com/cli/go-internal v0.0.0-20241025142207-6c48bcd5ce24/go.mod h1:rr9GNING0onuVw8MnracQHn7PcchnFlP882Y0II2KZk=
|
||||
github.com/cli/oauth v1.1.1 h1:459gD3hSjlKX9B1uXBuiAMdpXBUQ9QGf/NDcCpoQxPs=
|
||||
github.com/cli/oauth v1.1.1/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4=
|
||||
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
|
||||
|
|
@ -368,6 +368,8 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
|||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rodaine/table v1.0.1 h1:U/VwCnUxlVYxw8+NJiLIuCxA/xa6jL38MY3FYysVWWQ=
|
||||
github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
|
|
|
|||
|
|
@ -41,17 +41,18 @@ var HelpTopics = []helpTopic{
|
|||
{
|
||||
name: "environment",
|
||||
short: "Environment variables that can be used with gh",
|
||||
long: heredoc.Docf(`
|
||||
%[1]sGH_TOKEN%[1]s, %[1]sGITHUB_TOKEN%[1]s (in order of precedence): an authentication token for github.com
|
||||
API requests. Setting this avoids being prompted to authenticate and takes precedence over
|
||||
previously stored credentials.
|
||||
long: heredoc.Docf(`
|
||||
%[1]sGH_TOKEN%[1]s, %[1]sGITHUB_TOKEN%[1]s (in order of precedence): an authentication token that will be used when
|
||||
a command targets either github.com or a subdomain of ghe.com. Setting this avoids being prompted to
|
||||
authenticate and takes precedence over previously stored credentials.
|
||||
|
||||
%[1]sGH_ENTERPRISE_TOKEN%[1]s, %[1]sGITHUB_ENTERPRISE_TOKEN%[1]s (in order of precedence): an authentication
|
||||
token for API requests to GitHub Enterprise. When setting this, also set %[1]sGH_HOST%[1]s.
|
||||
%[1]sGH_ENTERPRISE_TOKEN%[1]s, %[1]sGITHUB_ENTERPRISE_TOKEN%[1]s (in order of precedence): an authentication
|
||||
token that will be used when a command targets a GitHub Enterprise Server host.
|
||||
|
||||
%[1]sGH_HOST%[1]s: specify the GitHub hostname for commands that would otherwise assume the
|
||||
"github.com" host when not in a context of an existing repository. When setting this,
|
||||
also set %[1]sGH_ENTERPRISE_TOKEN%[1]s.
|
||||
%[1]sGH_HOST%[1]s: specify the GitHub hostname for commands where a hostname has not been provided, or
|
||||
cannot be inferred from the context of a local Git repository. If this host was previously
|
||||
authenticated with, the stored credentials will be used. Otherwise, setting %[1]sGH_TOKEN%[1]s or
|
||||
%[1]sGH_ENTERPRISE_TOKEN%[1]s is required, depending on the targeted host.
|
||||
|
||||
%[1]sGH_REPO%[1]s: specify the GitHub repository in the %[1]s[HOST/]OWNER/REPO%[1]s format for commands
|
||||
that otherwise operate on a local repository.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue