Skip to content
GitLab
Next
Menu
Why GitLab
Pricing
Contact Sales
Explore
Why GitLab
Pricing
Contact Sales
Explore
Sign in
Get free trial
Primary navigation
Search or go to…
Project
cli
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Privacy statement
Keyboard shortcuts
?
What's new
4
Snippets
Groups
Projects
Show more breadcrumbs
GitLab.org
cli
Commits
12fb8a36
Commit
12fb8a36
authored
3 months ago
by
Anders Parslov
Committed by
Jay McCure
3 months ago
Browse files
Options
Downloads
Patches
Plain Diff
feat: add environment scope for export
parent
d8fa1d63
No related branches found
No related tags found
1 merge request
!1741
feat: add environment scope for export
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
commands/variable/export/export.go
+136
-13
136 additions, 13 deletions
commands/variable/export/export.go
commands/variable/export/export_test.go
+496
-59
496 additions, 59 deletions
commands/variable/export/export_test.go
docs/source/variable/export.md
+1
-0
1 addition, 0 deletions
docs/source/variable/export.md
with
633 additions
and
72 deletions
commands/variable/export/export.go
+
136
−
13
View file @
12fb8a36
...
...
@@ -3,6 +3,10 @@ package export
import
(
"encoding/json"
"fmt"
"io"
"os"
"regexp"
"strings"
"github.com/MakeNowJust/heredoc/v2"
"github.com/spf13/cobra"
...
...
@@ -22,6 +26,7 @@ type ExportOpts struct {
ValueSet
bool
Group
string
OutputFormat
string
Scope
string
Page
int
PerPage
int
...
...
@@ -77,11 +82,17 @@ func NewCmdExport(f *cmdutils.Factory, runE func(opts *ExportOpts) error) *cobra
cmd
.
Flags
()
.
IntVarP
(
&
opts
.
Page
,
"page"
,
"p"
,
1
,
"Page number."
)
cmd
.
Flags
()
.
IntVarP
(
&
opts
.
PerPage
,
"per-page"
,
"P"
,
100
,
"Number of items to list per page."
)
cmd
.
Flags
()
.
StringVarP
(
&
opts
.
OutputFormat
,
"format"
,
"F"
,
"json"
,
"Format of output: json, export, env."
)
cmd
.
Flags
()
.
StringVarP
(
&
opts
.
Scope
,
"scope"
,
"s"
,
"*"
,
"The environment_scope of the variables. Values: '*' (default), or specific environments."
)
return
cmd
}
func
exportRun
(
opts
*
ExportOpts
)
error
{
var
out
io
.
Writer
=
os
.
Stdout
if
opts
.
IO
!=
nil
&&
opts
.
IO
.
StdOut
!=
nil
{
out
=
opts
.
IO
.
StdOut
}
httpClient
,
err
:=
opts
.
HTTPClient
()
if
err
!=
nil
{
return
err
...
...
@@ -93,7 +104,6 @@ func exportRun(opts *ExportOpts) error {
}
if
opts
.
Group
!=
""
{
createVarOpts
:=
&
gitlab
.
ListGroupVariablesOptions
{
Page
:
opts
.
Page
,
PerPage
:
opts
.
PerPage
}
groupVariables
,
err
:=
api
.
ListGroupVariables
(
httpClient
,
opts
.
Group
,
createVarOpts
)
if
err
!=
nil
{
...
...
@@ -106,7 +116,7 @@ func exportRun(opts *ExportOpts) error {
return
nil
}
return
printGroupVariables
(
groupVariables
,
opts
)
return
printGroupVariables
(
groupVariables
,
opts
,
out
)
}
else
{
createVarOpts
:=
&
gitlab
.
ListProjectVariablesOptions
{
Page
:
opts
.
Page
,
PerPage
:
opts
.
PerPage
}
...
...
@@ -121,50 +131,163 @@ func exportRun(opts *ExportOpts) error {
return
nil
}
return
printProjectVariables
(
projectVariables
,
opts
)
return
printProjectVariables
(
projectVariables
,
opts
,
out
)
}
}
func
matchesScope
(
varScope
,
optScope
string
)
bool
{
if
varScope
==
"*"
||
optScope
==
"*"
{
return
true
}
if
varScope
==
optScope
{
return
true
}
if
strings
.
Contains
(
varScope
,
"*"
)
{
varPattern
:=
"^"
+
regexp
.
QuoteMeta
(
varScope
)
+
"$"
optPattern
:=
"^"
+
regexp
.
QuoteMeta
(
optScope
)
+
"$"
varPattern
=
strings
.
ReplaceAll
(
varPattern
,
`\*`
,
".*"
)
optPattern
=
strings
.
ReplaceAll
(
optPattern
,
`\*`
,
".*"
)
matchesVar
,
_
:=
regexp
.
MatchString
(
varPattern
,
optScope
)
matchesOpt
,
_
:=
regexp
.
MatchString
(
optPattern
,
varScope
)
return
matchesVar
||
matchesOpt
}
return
false
}
func
printGroupVariables
(
variables
[]
*
gitlab
.
GroupVariable
,
opts
*
ExportOpts
)
error
{
func
isValidEnvironmentScope
(
optScope
string
)
bool
{
pattern
:=
`^[a-zA-Z0-9\s\-_/${}\x20]+$`
re
,
_
:=
regexp
.
Compile
(
pattern
)
matched
:=
re
.
MatchString
(
optScope
)
return
matched
||
optScope
==
"*"
}
func
printGroupVariables
(
variables
[]
*
gitlab
.
GroupVariable
,
opts
*
ExportOpts
,
out
io
.
Writer
)
error
{
if
!
isValidEnvironmentScope
((
opts
.
Scope
))
{
return
fmt
.
Errorf
(
"invalid environment scope: %s"
,
opts
.
Scope
)
}
writtenKeys
:=
make
([]
string
,
0
)
switch
opts
.
OutputFormat
{
case
"env"
:
for
_
,
variable
:=
range
variables
{
fmt
.
Printf
(
"%s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
)
{
fmt
.
Fprintf
(
out
,
"%s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
writtenKeys
=
append
(
writtenKeys
,
variable
.
Key
)
}
}
}
keysMap
:=
CreateWrittenKeysMap
(
writtenKeys
)
for
_
,
variable
:=
range
variables
{
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
(
keysMap
[
variable
.
Key
])
&&
(
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
))
{
fmt
.
Fprintf
(
out
,
"%s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
}
}
}
case
"export"
:
for
_
,
variable
:=
range
variables
{
fmt
.
Printf
(
"export %s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
)
{
fmt
.
Fprintf
(
out
,
"export %s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
writtenKeys
=
append
(
writtenKeys
,
variable
.
Key
)
}
}
}
keysMap
:=
CreateWrittenKeysMap
(
writtenKeys
)
for
_
,
variable
:=
range
variables
{
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
(
keysMap
[
variable
.
Key
])
&&
(
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
))
{
fmt
.
Fprintf
(
out
,
"export %s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
}
}
}
case
"json"
:
res
,
err
:=
marshalJson
(
variables
)
filteredVariables
:=
make
([]
*
gitlab
.
GroupVariable
,
0
)
for
_
,
variable
:=
range
variables
{
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
filteredVariables
=
append
(
filteredVariables
,
variable
)
}
}
res
,
err
:=
marshalJson
(
filteredVariables
)
if
err
!=
nil
{
return
err
}
fmt
.
P
rintln
(
string
(
res
))
fmt
.
Fp
rintln
(
out
,
string
(
res
))
default
:
return
fmt
.
Errorf
(
"unsupported output format: %s"
,
opts
.
OutputFormat
)
}
return
nil
}
func
printProjectVariables
(
variables
[]
*
gitlab
.
ProjectVariable
,
opts
*
ExportOpts
)
error
{
func
printProjectVariables
(
variables
[]
*
gitlab
.
ProjectVariable
,
opts
*
ExportOpts
,
out
io
.
Writer
)
error
{
if
!
isValidEnvironmentScope
((
opts
.
Scope
))
{
return
fmt
.
Errorf
(
"invalid environment scope: %s"
,
opts
.
Scope
)
}
writtenKeys
:=
make
([]
string
,
0
)
switch
opts
.
OutputFormat
{
case
"env"
:
for
_
,
variable
:=
range
variables
{
fmt
.
Printf
(
"%s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
)
{
fmt
.
Fprintf
(
out
,
"%s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
writtenKeys
=
append
(
writtenKeys
,
variable
.
Key
)
}
}
}
keysMap
:=
CreateWrittenKeysMap
(
writtenKeys
)
for
_
,
variable
:=
range
variables
{
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
(
keysMap
[
variable
.
Key
])
&&
(
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
))
{
fmt
.
Fprintf
(
out
,
"%s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
}
}
}
case
"export"
:
for
_
,
variable
:=
range
variables
{
fmt
.
Printf
(
"export %s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
)
{
fmt
.
Fprintf
(
out
,
"export %s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
writtenKeys
=
append
(
writtenKeys
,
variable
.
Key
)
}
}
}
keysMap
:=
CreateWrittenKeysMap
(
writtenKeys
)
for
_
,
variable
:=
range
variables
{
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
if
!
(
keysMap
[
variable
.
Key
])
&&
(
strings
.
Contains
(
variable
.
EnvironmentScope
,
"*"
))
{
fmt
.
Fprintf
(
out
,
"export %s=%s
\n
"
,
variable
.
Key
,
variable
.
Value
)
}
}
}
case
"json"
:
res
,
err
:=
marshalJson
(
variables
)
filteredVariables
:=
make
([]
*
gitlab
.
ProjectVariable
,
0
)
for
_
,
variable
:=
range
variables
{
if
matchesScope
(
variable
.
EnvironmentScope
,
opts
.
Scope
)
{
filteredVariables
=
append
(
filteredVariables
,
variable
)
}
}
res
,
err
:=
marshalJson
(
filteredVariables
)
if
err
!=
nil
{
return
err
}
fmt
.
P
rintln
(
string
(
res
))
fmt
.
Fp
rintln
(
out
,
string
(
res
))
default
:
return
fmt
.
Errorf
(
"unsupported output format: %s"
,
opts
.
OutputFormat
)
}
return
nil
}
func
CreateWrittenKeysMap
(
writtenKeys
[]
string
)
map
[
string
]
bool
{
keysMap
:=
make
(
map
[
string
]
bool
)
for
_
,
key
:=
range
writtenKeys
{
keysMap
[
key
]
=
true
}
return
keysMap
}
This diff is collapsed.
Click to expand it.
commands/variable/export/export_test.go
+
496
−
59
View file @
12fb8a36
...
...
@@ -5,6 +5,7 @@ import (
"net/http"
"testing"
"github.com/MakeNowJust/heredoc/v2"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
"github.com/xanzy/go-gitlab"
...
...
@@ -95,85 +96,521 @@ func Test_exportRun_project(t *testing.T) {
mockProjectVariables
:=
[]
gitlab
.
ProjectVariable
{
{
Key
:
"VAR1"
,
Value
:
"value1"
,
Key
:
"VAR1"
,
Value
:
"value1"
,
EnvironmentScope
:
"dev"
,
},
{
Key
:
"VAR2"
,
Value
:
"value2"
,
Key
:
"VAR2"
,
Value
:
"value2.1"
,
EnvironmentScope
:
"prod"
,
},
{
Key
:
"VAR2"
,
Value
:
"value2.2"
,
EnvironmentScope
:
"*"
,
},
{
Key
:
"VAR3"
,
Value
:
"value3"
,
EnvironmentScope
:
"dev/a"
,
},
{
Key
:
"VAR4"
,
Value
:
"value4.1"
,
EnvironmentScope
:
"dev/b"
,
},
{
Key
:
"VAR4"
,
Value
:
"value4.2"
,
EnvironmentScope
:
"feature-1"
,
},
{
Key
:
"VAR4"
,
Value
:
"value4.3"
,
EnvironmentScope
:
"feature-2"
,
},
{
Key
:
"VAR5"
,
Value
:
"value5"
,
EnvironmentScope
:
"feature-*"
,
},
}
io
,
_
,
stdout
,
_
:=
iostreams
.
Test
()
outputFormats
:=
[]
string
{
"env"
,
"export"
,
"json"
}
tests
:=
[]
struct
{
scope
string
format
string
expectedOutput
string
}{
{
scope
:
"*"
,
format
:
"json"
,
expectedOutput
:
heredoc
.
Doc
(
`
[
{
"key": "VAR1",
"value": "value1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev",
"description": ""
},
{
"key": "VAR2",
"value": "value2.1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "prod",
"description": ""
},
{
"key": "VAR2",
"value": "value2.2",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "*",
"description": ""
},
{
"key": "VAR3",
"value": "value3",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev/a",
"description": ""
},
{
"key": "VAR4",
"value": "value4.1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev/b",
"description": ""
},
{
"key": "VAR4",
"value": "value4.2",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "feature-1",
"description": ""
},
{
"key": "VAR4",
"value": "value4.3",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "feature-2",
"description": ""
},
{
"key": "VAR5",
"value": "value5",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "feature-*",
"description": ""
}
]
`
),
},
{
scope
:
"dev/b"
,
format
:
"json"
,
expectedOutput
:
heredoc
.
Doc
(
`
[
{
"key": "VAR2",
"value": "value2.2",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "*",
"description": ""
},
{
"key": "VAR4",
"value": "value4.1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev/b",
"description": ""
}
]
`
),
},
{
scope
:
"*"
,
format
:
"env"
,
expectedOutput
:
"VAR1=value1
\n
VAR2=value2.1
\n
VAR3=value3
\n
VAR4=value4.1
\n
VAR4=value4.2
\n
VAR4=value4.3
\n
VAR5=value5
\n
"
,
},
{
scope
:
"*"
,
format
:
"export"
,
expectedOutput
:
"export VAR1=value1
\n
export VAR2=value2.1
\n
export VAR3=value3
\n
export VAR4=value4.1
\n
export VAR4=value4.2
\n
export VAR4=value4.3
\n
export VAR5=value5
\n
"
,
},
{
scope
:
"dev"
,
format
:
"env"
,
expectedOutput
:
"VAR1=value1
\n
VAR2=value2.2
\n
"
,
},
{
scope
:
"dev"
,
format
:
"export"
,
expectedOutput
:
"export VAR1=value1
\n
export VAR2=value2.2
\n
"
,
},
{
scope
:
"prod"
,
format
:
"env"
,
expectedOutput
:
"VAR2=value2.1
\n
"
,
},
{
scope
:
"prod"
,
format
:
"export"
,
expectedOutput
:
"export VAR2=value2.1
\n
"
,
},
{
scope
:
"dev/a"
,
format
:
"env"
,
expectedOutput
:
"VAR3=value3
\n
VAR2=value2.2
\n
"
,
},
{
scope
:
"dev/a"
,
format
:
"export"
,
expectedOutput
:
"export VAR3=value3
\n
export VAR2=value2.2
\n
"
,
},
{
scope
:
"feature-1"
,
format
:
"env"
,
expectedOutput
:
"VAR4=value4.2
\n
VAR2=value2.2
\n
VAR5=value5
\n
"
,
},
{
scope
:
"feature-1"
,
format
:
"export"
,
expectedOutput
:
"export VAR4=value4.2
\n
export VAR2=value2.2
\n
export VAR5=value5
\n
"
,
},
{
scope
:
"feature-2"
,
format
:
"env"
,
expectedOutput
:
"VAR4=value4.3
\n
VAR2=value2.2
\n
VAR5=value5
\n
"
,
},
{
scope
:
"feature-2"
,
format
:
"export"
,
expectedOutput
:
"export VAR4=value4.3
\n
export VAR2=value2.2
\n
export VAR5=value5
\n
"
,
},
}
for
_
,
format
:=
range
outputFormats
{
reg
.
RegisterResponder
(
http
.
MethodGet
,
"https://gitlab.com/api/v4/projects/owner%2Frepo/variables?page=1&per_page=10"
,
httpmock
.
NewJSONResponse
(
http
.
StatusOK
,
mockProjectVariables
),
)
opts
:=
&
ExportOpts
{
HTTPClient
:
func
()
(
*
gitlab
.
Client
,
error
)
{
a
,
_
:=
api
.
TestClient
(
&
http
.
Client
{
Transport
:
reg
},
""
,
"gitlab.com"
,
false
)
return
a
.
Lab
(),
nil
},
BaseRepo
:
func
()
(
glrepo
.
Interface
,
error
)
{
return
glrepo
.
FromFullName
(
"owner/repo"
)
},
IO
:
io
,
Page
:
1
,
PerPage
:
10
,
OutputFormat
:
format
,
}
_
,
_
=
opts
.
HTTPClient
()
err
:=
exportRun
(
opts
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
""
,
stdout
.
String
())
for
_
,
test
:=
range
tests
{
t
.
Run
(
test
.
scope
+
"_"
+
test
.
format
,
func
(
t
*
testing
.
T
)
{
reg
.
RegisterResponder
(
http
.
MethodGet
,
"https://gitlab.com/api/v4/projects/owner%2Frepo/variables?page=1&per_page=10"
,
httpmock
.
NewJSONResponse
(
http
.
StatusOK
,
mockProjectVariables
),
)
opts
:=
&
ExportOpts
{
HTTPClient
:
func
()
(
*
gitlab
.
Client
,
error
)
{
a
,
_
:=
api
.
TestClient
(
&
http
.
Client
{
Transport
:
reg
},
""
,
"gitlab.com"
,
false
)
return
a
.
Lab
(),
nil
},
BaseRepo
:
func
()
(
glrepo
.
Interface
,
error
)
{
return
glrepo
.
FromFullName
(
"owner/repo"
)
},
IO
:
io
,
Page
:
1
,
PerPage
:
10
,
OutputFormat
:
test
.
format
,
Scope
:
test
.
scope
,
}
_
,
_
=
opts
.
HTTPClient
()
err
:=
exportRun
(
opts
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
test
.
expectedOutput
,
stdout
.
String
())
stdout
.
Reset
()
})
}
}
func
Test_exportRun_group
(
t
*
testing
.
T
)
{
reg
:=
&
httpmock
.
Mocker
{
MatchURL
:
httpmock
.
FullURL
,
}
defer
reg
.
Verify
(
t
)
mockGroupVariables
:=
[]
gitlab
.
GroupVariable
{
{
Key
:
"VAR1"
,
Value
:
"value1"
,
Key
:
"VAR1"
,
Value
:
"value1"
,
EnvironmentScope
:
"dev"
,
},
{
Key
:
"VAR2"
,
Value
:
"value2"
,
Key
:
"VAR2"
,
Value
:
"value2.1"
,
EnvironmentScope
:
"prod"
,
},
{
Key
:
"VAR2"
,
Value
:
"value2.2"
,
EnvironmentScope
:
"*"
,
},
{
Key
:
"VAR3"
,
Value
:
"value3"
,
EnvironmentScope
:
"dev/a"
,
},
{
Key
:
"VAR4"
,
Value
:
"value4.1"
,
EnvironmentScope
:
"dev/b"
,
},
{
Key
:
"VAR4"
,
Value
:
"value4.2"
,
EnvironmentScope
:
"feature-1"
,
},
{
Key
:
"VAR4"
,
Value
:
"value4.3"
,
EnvironmentScope
:
"feature-2"
,
},
{
Key
:
"VAR5"
,
Value
:
"value5"
,
EnvironmentScope
:
"feature-*"
,
},
}
reg
:=
&
httpmock
.
Mocker
{
MatchURL
:
httpmock
.
FullURL
,
}
defer
reg
.
Verify
(
t
)
io
,
_
,
stdout
,
_
:=
iostreams
.
Test
()
outputFormats
:=
[]
string
{
"env"
,
"export"
,
"json"
}
for
_
,
format
:=
range
outputFormats
{
reg
.
RegisterResponder
(
http
.
MethodGet
,
"https://gitlab.com/api/v4/groups/GROUP/variables?page=7&per_page=77"
,
httpmock
.
NewJSONResponse
(
http
.
StatusOK
,
mockGroupVariables
),
)
tests
:=
[]
struct
{
scope
string
format
string
expectedOutput
string
}{
{
scope
:
"*"
,
format
:
"json"
,
expectedOutput
:
heredoc
.
Doc
(
`
[
{
"key": "VAR1",
"value": "value1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev",
"description": ""
},
{
"key": "VAR2",
"value": "value2.1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "prod",
"description": ""
},
{
"key": "VAR2",
"value": "value2.2",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "*",
"description": ""
},
{
"key": "VAR3",
"value": "value3",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev/a",
"description": ""
},
{
"key": "VAR4",
"value": "value4.1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev/b",
"description": ""
},
{
"key": "VAR4",
"value": "value4.2",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "feature-1",
"description": ""
},
{
"key": "VAR4",
"value": "value4.3",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "feature-2",
"description": ""
},
{
"key": "VAR5",
"value": "value5",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "feature-*",
"description": ""
}
]
`
),
},
{
scope
:
"dev/b"
,
format
:
"json"
,
expectedOutput
:
heredoc
.
Doc
(
`
[
{
"key": "VAR2",
"value": "value2.2",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "*",
"description": ""
},
{
"key": "VAR4",
"value": "value4.1",
"variable_type": "",
"protected": false,
"masked": false,
"raw": false,
"environment_scope": "dev/b",
"description": ""
}
]
`
),
},
{
scope
:
"*"
,
format
:
"env"
,
expectedOutput
:
"VAR1=value1
\n
VAR2=value2.1
\n
VAR3=value3
\n
VAR4=value4.1
\n
VAR4=value4.2
\n
VAR4=value4.3
\n
VAR5=value5
\n
"
,
},
{
scope
:
"*"
,
format
:
"export"
,
expectedOutput
:
"export VAR1=value1
\n
export VAR2=value2.1
\n
export VAR3=value3
\n
export VAR4=value4.1
\n
export VAR4=value4.2
\n
export VAR4=value4.3
\n
export VAR5=value5
\n
"
,
},
{
scope
:
"dev"
,
format
:
"env"
,
expectedOutput
:
"VAR1=value1
\n
VAR2=value2.2
\n
"
,
},
{
scope
:
"dev"
,
format
:
"export"
,
expectedOutput
:
"export VAR1=value1
\n
export VAR2=value2.2
\n
"
,
},
{
scope
:
"prod"
,
format
:
"env"
,
expectedOutput
:
"VAR2=value2.1
\n
"
,
},
{
scope
:
"prod"
,
format
:
"export"
,
expectedOutput
:
"export VAR2=value2.1
\n
"
,
},
{
scope
:
"dev/a"
,
format
:
"env"
,
expectedOutput
:
"VAR3=value3
\n
VAR2=value2.2
\n
"
,
},
{
scope
:
"dev/a"
,
format
:
"export"
,
expectedOutput
:
"export VAR3=value3
\n
export VAR2=value2.2
\n
"
,
},
{
scope
:
"feature-1"
,
format
:
"env"
,
expectedOutput
:
"VAR4=value4.2
\n
VAR2=value2.2
\n
VAR5=value5
\n
"
,
},
{
scope
:
"feature-1"
,
format
:
"export"
,
expectedOutput
:
"export VAR4=value4.2
\n
export VAR2=value2.2
\n
export VAR5=value5
\n
"
,
},
{
scope
:
"feature-2"
,
format
:
"env"
,
expectedOutput
:
"VAR4=value4.3
\n
VAR2=value2.2
\n
VAR5=value5
\n
"
,
},
{
scope
:
"feature-2"
,
format
:
"export"
,
expectedOutput
:
"export VAR4=value4.3
\n
export VAR2=value2.2
\n
export VAR5=value5
\n
"
,
},
}
opts
:=
&
ExportOpts
{
HTTPClient
:
func
()
(
*
gitlab
.
Client
,
error
)
{
a
,
_
:=
api
.
TestClient
(
&
http
.
Client
{
Transport
:
reg
},
""
,
"gitlab.com"
,
false
)
return
a
.
Lab
(),
nil
},
BaseRepo
:
func
()
(
glrepo
.
Interface
,
error
)
{
return
glrepo
.
FromFullName
(
"owner/repo"
)
},
IO
:
io
,
Page
:
7
,
PerPage
:
77
,
Group
:
"GROUP"
,
OutputFormat
:
format
,
}
_
,
_
=
opts
.
HTTPClient
()
err
:=
exportRun
(
opts
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
""
,
stdout
.
String
())
for
_
,
test
:=
range
tests
{
t
.
Run
(
test
.
scope
+
"_"
+
test
.
format
,
func
(
t
*
testing
.
T
)
{
reg
.
RegisterResponder
(
http
.
MethodGet
,
"https://gitlab.com/api/v4/groups/group/variables?page=1&per_page=10"
,
httpmock
.
NewJSONResponse
(
http
.
StatusOK
,
mockGroupVariables
),
)
opts
:=
&
ExportOpts
{
HTTPClient
:
func
()
(
*
gitlab
.
Client
,
error
)
{
a
,
_
:=
api
.
TestClient
(
&
http
.
Client
{
Transport
:
reg
},
""
,
"gitlab.com"
,
false
)
return
a
.
Lab
(),
nil
},
BaseRepo
:
func
()
(
glrepo
.
Interface
,
error
)
{
return
glrepo
.
FromFullName
(
"owner/repo"
)
},
IO
:
io
,
Page
:
1
,
PerPage
:
10
,
OutputFormat
:
test
.
format
,
Scope
:
test
.
scope
,
Group
:
"group"
,
}
_
,
_
=
opts
.
HTTPClient
()
err
:=
exportRun
(
opts
)
assert
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
test
.
expectedOutput
,
stdout
.
String
())
stdout
.
Reset
()
})
}
}
This diff is collapsed.
Click to expand it.
docs/source/variable/export.md
+
1
−
0
View file @
12fb8a36
...
...
@@ -41,6 +41,7 @@ glab variable export --group gitlab-org --per-page 1000 --page 1
-p, --page int Page number. (default 1)
-P, --per-page int Number of items to list per page. (default 100)
-R, --repo OWNER/REPO Select another repository. Can use either OWNER/REPO or `GROUP/NAMESPACE/REPO` format. Also accepts full URL or Git URL.
-s, --scope string The environment_scope of the variables. Values: '*' (default), or specific environments. (default "*")
```
## Options inherited from parent commands
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment