Merge branch 'trunk' into verify-provenance-predicate-by-default

This commit is contained in:
Meredith Lancaster 2024-10-25 13:58:20 -06:00 committed by GitHub
commit c552224081
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 197 additions and 17 deletions

View file

@ -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.

View file

@ -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 != "" {

View 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

View 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$'

View file

@ -0,0 +1,3 @@
# Check the authentication status
exec gh auth status --hostname $GH_HOST
stdout '✓ Logged in to '

View file

@ -0,0 +1,3 @@
# Check authentication token
exec gh auth token --hostname $GH_HOST
stdout $GH_TOKEN

View 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
View 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'

View 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}

View 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
View file

@ -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
View file

@ -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=

View file

@ -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.