Merge branch 'master' into help-by-default
This commit is contained in:
commit
eb1834df49
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
* @erincall @grinnellian @kav @josmo
|
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Unexpected or broken behavior
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**What I tried to do:**
|
||||
<!-- e.g. run a helm installation -->
|
||||
|
||||
**What happened:**
|
||||
<!-- describe the faulty behavior -->
|
||||
|
||||
**More info:**
|
||||
<!-- contents of .drone.yml, etc. -->
|
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest a new feature
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**The problem I'm trying to solve:**
|
||||
<!-- describe what you'd like to be able to accomplish -->
|
||||
|
||||
**How I imagine it working:**
|
||||
<!-- e.g. configuration that could go in .drone.yml -->
|
8
.github/pull_request_template.md
vendored
Normal file
8
.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
**Please replace this line with "fixes #ISSUE_NUMBER" (or "relates to #ISSUE_NUMBER", if it is not a complete fix)**
|
||||
|
||||
Pre-merge checklist:
|
||||
|
||||
* [ ] Code changes have tests
|
||||
* [ ] Any changes to the config are documented in `docs/parameter_reference.md`
|
||||
* [ ] Any new _required_ config is documented in `README.md`
|
||||
* [ ] Any large changes have been verified by running a Drone job
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,3 +13,5 @@
|
|||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
.env
|
||||
.secrets
|
||||
|
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [workwithus@pelo.tech](mailto:workwithus@pelo.tech). All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
48
docs/contributing.md
Normal file
48
docs/contributing.md
Normal file
|
@ -0,0 +1,48 @@
|
|||
# Contributing to drone-helm3
|
||||
|
||||
We're glad you're interested in contributing! Here are some guidelines that will help make sure everyone has a good experience:
|
||||
|
||||
## Submitting a patch
|
||||
|
||||
Before you start working on a change, please make sure there's an associated issue. It doesn't need to be thoroughly scrutinized and dissected, but it needs to exist.
|
||||
|
||||
Please put the relevant issue number in the first line of your commit messages, e.g. `vorpalize the frabjulator [#42]`. Branch names do not need issue numbers, but feel free to include them if you like.
|
||||
|
||||
We encourage you to follow [the guidelines in Pro Git](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines) when making commits. In short:
|
||||
|
||||
* Commit early and commit often.
|
||||
* Make the first line of the commit message concise--no more than 50 characters or so.
|
||||
* Make the rest of the commit message verbose--information about _why_ you did what you did is particularly helpful.
|
||||
|
||||
Once you're satisfied with your work, send us a pull request. If you'd like, you can send the pull request _before_ you're satisfied with your work; just be sure to mark the PR a draft or put `[WIP]` in the title.
|
||||
|
||||
## How to run the tests
|
||||
|
||||
We use `go test`, `go vet`, and `golint`:
|
||||
|
||||
```
|
||||
go test ./cmd/... ./internal/...
|
||||
go vet ./cmd/... ./internal/...
|
||||
golint -set_exit_status ./cmd/... ./internal/...
|
||||
```
|
||||
|
||||
If you have [the Drone cli tool](https://docs.drone.io/cli/install/) installed, you can also use `drone exec --include test --include lint`.
|
||||
|
||||
## Testing the plugin end-to-end
|
||||
|
||||
Although we aim to make the internal tests as thorough as possible, they can't test drone-helm3's integration with drone and helm themselves. However, you can test a change manually by building an image and running it with a fixture repository.
|
||||
|
||||
You will need:
|
||||
|
||||
* Access to a docker image registry. This document assumes you'll use [Docker Hub](https://hub.docker.com).
|
||||
* [The Drone cli tool](https://docs.drone.io/cli/install/).
|
||||
* A fixture repository--a directory with a `.drone.yml` and a helm chart. If you don't have one handy, try adding a `.drone.yml` to a chart from [Helm's "stable" repository](https://github.com/helm/charts/tree/master/stable/).
|
||||
* Access to a kubernetes cluster (unless `lint` or `dry_run` is sufficient for your purposes).
|
||||
|
||||
Once you have what you need, you can publish and consume an image with your changes:
|
||||
|
||||
1. [Create a repository on Docker Hub](https://hub.docker.com/repository/create). This document assumes you've called it drone-helm3-testing.
|
||||
1. Create a `.secrets` file with your docker credentials (see [example.secrets](./example.secrets) for an example). While you can use your Docker Hub password, it's better to [generate an access token](https://hub.docker.com/settings/security) and use that instead.
|
||||
1. Use Drone to build and publish an image with your changes: `drone exec --secret-file ./secrets --event push`
|
||||
1. In the `.drone.yml` of your fixture repository, set the `image` for each relevant stanza to `your_dockerhub_username/drone-helm3-testing`
|
||||
1. Use `drone exec` in the fixture repo to verify your changes.
|
3
docs/example.secrets
Normal file
3
docs/example.secrets
Normal file
|
@ -0,0 +1,3 @@
|
|||
DOCKER_PASSWORD=your_access_token
|
||||
DOCKER_USERNAME=your_dockerhub_username
|
||||
PLUGIN_REPO=your_dockerhub_username/drone-helm3-testing
|
|
@ -4,7 +4,7 @@
|
|||
| Param name | Type | Purpose |
|
||||
|---------------------|-----------------|---------|
|
||||
| helm_command | string | Indicates the operation to perform. Recommended, but not required. Valid options are `upgrade`, `uninstall`, `lint`, and `help`. |
|
||||
| update_dependencies | boolean | Calls `helm dependency update` before running the main command. **Not currently implemented**; see [#25](https://github.com/pelotech/drone-helm3/issues/25).|
|
||||
| update_dependencies | boolean | Calls `helm dependency update` before running the main command.|
|
||||
| helm_repos | list\<string\> | Calls `helm repo add $repo` before running the main command. Each string should be formatted as `repo_name=https://repo.url/`. **Not currently implemented**; see [#26](https://github.com/pelotech/drone-helm3/issues/26). |
|
||||
| namespace | string | Kubernetes namespace to use for this operation. |
|
||||
| prefix | string | Expect environment variables to be prefixed with the given string. For more details, see "Using the prefix setting" below. **Not currently implemented**; see [#19](https://github.com/pelotech/drone-helm3/issues/19). |
|
||||
|
@ -58,6 +58,7 @@ Uninstallations are triggered when the `helm_command` setting is "uninstall" or
|
|||
| dry_run | boolean | | Pass `--dry-run` to `helm uninstall`. |
|
||||
| timeout | duration | | Timeout for any *individual* Kubernetes operation. The uninstallation's full runtime may exceed this duration. |
|
||||
| skip_tls_verify | boolean | | Connect to the Kubernetes cluster without checking for a valid TLS certificate. Not recommended in production. |
|
||||
| chart | string | | Required when the global `update_dependencies` parameter is true. No effect otherwise. |
|
||||
|
||||
### Where to put settings
|
||||
|
||||
|
@ -67,6 +68,7 @@ Any setting (with the exception of `prefix`; [see below](#user-content-using-the
|
|||
|
||||
* Booleans can be yaml's `true` and `false` literals or the strings `"true"` and `"false"`.
|
||||
* Durations are strings formatted with the syntax accepted by [golang's ParseDuration function](https://golang.org/pkg/time/#ParseDuration) (e.g. 5m30s)
|
||||
* For backward-compatibility with drone-helm, a duration can also be an integer, in which case it will be interpreted to mean seconds.
|
||||
* List\<string\>s can be a yaml sequence or a comma-separated string.
|
||||
|
||||
All of the following are equivalent:
|
||||
|
|
|
@ -4,8 +4,11 @@ import (
|
|||
"fmt"
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"io"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var justNumbers = regexp.MustCompile(`^\d+$`)
|
||||
|
||||
// The Config struct captures the `settings` and `environment` blocks in the application's drone
|
||||
// config. Configuration in drone's `settings` block arrives as uppercase env vars matching the
|
||||
// config key, prefixed with `PLUGIN_`. Config from the `environment` block is uppercased, but does
|
||||
|
@ -62,6 +65,10 @@ func NewConfig(stdout, stderr io.Writer) (*Config, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if justNumbers.MatchString(cfg.Timeout) {
|
||||
cfg.Timeout = fmt.Sprintf("%ss", cfg.Timeout)
|
||||
}
|
||||
|
||||
if cfg.Debug && cfg.Stderr != nil {
|
||||
cfg.logDebug()
|
||||
}
|
||||
|
|
|
@ -106,6 +106,13 @@ func (suite *ConfigTestSuite) TestNewConfigWithConflictingVariables() {
|
|||
suite.Equal("2m30s", cfg.Timeout)
|
||||
}
|
||||
|
||||
func (suite *ConfigTestSuite) TestNewConfigInfersNumbersAreSeconds() {
|
||||
suite.setenv("PLUGIN_TIMEOUT", "42")
|
||||
cfg, err := NewConfig(&strings.Builder{}, &strings.Builder{})
|
||||
suite.Require().NoError(err)
|
||||
suite.Equal("42s", cfg.Timeout)
|
||||
}
|
||||
|
||||
func (suite *ConfigTestSuite) TestNewConfigSetsWriters() {
|
||||
stdout := &strings.Builder{}
|
||||
stderr := &strings.Builder{}
|
||||
|
|
|
@ -69,7 +69,6 @@ func determineSteps(cfg Config) *func(Config) []Step {
|
|||
return &help
|
||||
default:
|
||||
switch cfg.DroneEvent {
|
||||
// Note: These events are documented in docs/upgrade_settings.yml. Any changes here should be reflected there.
|
||||
case "push", "tag", "deployment", "pull_request", "promote", "rollback":
|
||||
return &upgrade
|
||||
case "delete":
|
||||
|
@ -97,7 +96,9 @@ func (p *Plan) Execute() error {
|
|||
|
||||
var upgrade = func(cfg Config) []Step {
|
||||
steps := initKube(cfg)
|
||||
|
||||
if cfg.UpdateDependencies {
|
||||
steps = append(steps, depUpdate(cfg)...)
|
||||
}
|
||||
steps = append(steps, &run.Upgrade{
|
||||
Chart: cfg.Chart,
|
||||
Release: cfg.Release,
|
||||
|
@ -114,6 +115,9 @@ var upgrade = func(cfg Config) []Step {
|
|||
|
||||
var uninstall = func(cfg Config) []Step {
|
||||
steps := initKube(cfg)
|
||||
if cfg.UpdateDependencies {
|
||||
steps = append(steps, depUpdate(cfg)...)
|
||||
}
|
||||
steps = append(steps, &run.Uninstall{
|
||||
Release: cfg.Release,
|
||||
DryRun: cfg.DryRun,
|
||||
|
@ -123,11 +127,15 @@ var uninstall = func(cfg Config) []Step {
|
|||
}
|
||||
|
||||
var lint = func(cfg Config) []Step {
|
||||
lint := &run.Lint{
|
||||
Chart: cfg.Chart,
|
||||
steps := make([]Step, 0)
|
||||
if cfg.UpdateDependencies {
|
||||
steps = append(steps, depUpdate(cfg)...)
|
||||
}
|
||||
steps = append(steps, &run.Lint{
|
||||
Chart: cfg.Chart,
|
||||
})
|
||||
|
||||
return []Step{lint}
|
||||
return steps
|
||||
}
|
||||
|
||||
var help = func(cfg Config) []Step {
|
||||
|
@ -150,3 +158,11 @@ func initKube(cfg Config) []Step {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
func depUpdate(cfg Config) []Step {
|
||||
return []Step{
|
||||
&run.DepUpdate{
|
||||
Chart: cfg.Chart,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,17 @@ func (suite *PlanTestSuite) TestUpgrade() {
|
|||
suite.Equal(expected, upgrade)
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestDel() {
|
||||
func (suite *PlanTestSuite) TestUpgradeWithUpdateDependencies() {
|
||||
cfg := Config{
|
||||
UpdateDependencies: true,
|
||||
}
|
||||
steps := upgrade(cfg)
|
||||
suite.Require().Equal(3, len(steps), "upgrade should have a third step when DepUpdate is true")
|
||||
suite.IsType(&run.InitKube{}, steps[0])
|
||||
suite.IsType(&run.DepUpdate{}, steps[1])
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestUninstall() {
|
||||
cfg := Config{
|
||||
KubeToken: "b2YgbXkgYWZmZWN0aW9u",
|
||||
SkipTLSVerify: true,
|
||||
|
@ -205,6 +215,16 @@ func (suite *PlanTestSuite) TestDel() {
|
|||
suite.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestUninstallWithUpdateDependencies() {
|
||||
cfg := Config{
|
||||
UpdateDependencies: true,
|
||||
}
|
||||
steps := uninstall(cfg)
|
||||
suite.Require().Equal(3, len(steps), "uninstall should have a third step when DepUpdate is true")
|
||||
suite.IsType(&run.InitKube{}, steps[0])
|
||||
suite.IsType(&run.DepUpdate{}, steps[1])
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestInitKube() {
|
||||
cfg := Config{
|
||||
KubeToken: "cXVlZXIgY2hhcmFjdGVyCg==",
|
||||
|
@ -231,6 +251,23 @@ func (suite *PlanTestSuite) TestInitKube() {
|
|||
suite.Equal(expected, init)
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestDepUpdate() {
|
||||
cfg := Config{
|
||||
UpdateDependencies: true,
|
||||
Chart: "scatterplot",
|
||||
}
|
||||
|
||||
steps := depUpdate(cfg)
|
||||
suite.Require().Equal(1, len(steps), "depUpdate should return one step")
|
||||
suite.Require().IsType(&run.DepUpdate{}, steps[0])
|
||||
update, _ := steps[0].(*run.DepUpdate)
|
||||
|
||||
expected := &run.DepUpdate{
|
||||
Chart: "scatterplot",
|
||||
}
|
||||
suite.Equal(expected, update)
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestLint() {
|
||||
cfg := Config{
|
||||
Chart: "./flow",
|
||||
|
@ -245,6 +282,15 @@ func (suite *PlanTestSuite) TestLint() {
|
|||
suite.Equal(want, steps[0])
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestLintWithUpdateDependencies() {
|
||||
cfg := Config{
|
||||
UpdateDependencies: true,
|
||||
}
|
||||
steps := lint(cfg)
|
||||
suite.Require().Equal(2, len(steps), "lint should have a second step when DepUpdate is true")
|
||||
suite.IsType(&run.DepUpdate{}, steps[0])
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestDeterminePlanUpgradeCommand() {
|
||||
cfg := Config{
|
||||
Command: "upgrade",
|
||||
|
|
44
internal/run/depupdate.go
Normal file
44
internal/run/depupdate.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package run
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// DepUpdate is an execution step that calls `helm dependency update` when executed.
|
||||
type DepUpdate struct {
|
||||
Chart string
|
||||
cmd cmd
|
||||
}
|
||||
|
||||
// Execute executes the `helm upgrade` command.
|
||||
func (d *DepUpdate) Execute(_ Config) error {
|
||||
return d.cmd.Run()
|
||||
}
|
||||
|
||||
// Prepare gets the DepUpdate ready to execute.
|
||||
func (d *DepUpdate) Prepare(cfg Config) error {
|
||||
if d.Chart == "" {
|
||||
return fmt.Errorf("chart is required")
|
||||
}
|
||||
|
||||
args := make([]string, 0)
|
||||
|
||||
if cfg.Namespace != "" {
|
||||
args = append(args, "--namespace", cfg.Namespace)
|
||||
}
|
||||
if cfg.Debug {
|
||||
args = append(args, "--debug")
|
||||
}
|
||||
|
||||
args = append(args, "dependency", "update", d.Chart)
|
||||
|
||||
d.cmd = command(helmBin, args...)
|
||||
d.cmd.Stdout(cfg.Stdout)
|
||||
d.cmd.Stderr(cfg.Stderr)
|
||||
|
||||
if cfg.Debug {
|
||||
fmt.Fprintf(cfg.Stderr, "Generated command: '%s'\n", d.cmd.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
128
internal/run/depupdate_test.go
Normal file
128
internal/run/depupdate_test.go
Normal file
|
@ -0,0 +1,128 @@
|
|||
package run
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type DepUpdateTestSuite struct {
|
||||
suite.Suite
|
||||
ctrl *gomock.Controller
|
||||
mockCmd *Mockcmd
|
||||
originalCommand func(string, ...string) cmd
|
||||
}
|
||||
|
||||
func (suite *DepUpdateTestSuite) BeforeTest(_, _ string) {
|
||||
suite.ctrl = gomock.NewController(suite.T())
|
||||
suite.mockCmd = NewMockcmd(suite.ctrl)
|
||||
|
||||
suite.originalCommand = command
|
||||
command = func(path string, args ...string) cmd { return suite.mockCmd }
|
||||
}
|
||||
|
||||
func (suite *DepUpdateTestSuite) AfterTest(_, _ string) {
|
||||
command = suite.originalCommand
|
||||
}
|
||||
|
||||
func TestDepUpdateTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(DepUpdateTestSuite))
|
||||
}
|
||||
|
||||
func (suite *DepUpdateTestSuite) TestPrepareAndExecute() {
|
||||
defer suite.ctrl.Finish()
|
||||
|
||||
stdout := strings.Builder{}
|
||||
stderr := strings.Builder{}
|
||||
cfg := Config{
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
}
|
||||
|
||||
command = func(path string, args ...string) cmd {
|
||||
suite.Equal(helmBin, path)
|
||||
suite.Equal([]string{"dependency", "update", "your_top_songs_2019"}, args)
|
||||
|
||||
return suite.mockCmd
|
||||
}
|
||||
suite.mockCmd.EXPECT().
|
||||
Stdout(&stdout)
|
||||
suite.mockCmd.EXPECT().
|
||||
Stderr(&stderr)
|
||||
suite.mockCmd.EXPECT().
|
||||
Run().
|
||||
Times(1)
|
||||
|
||||
d := DepUpdate{
|
||||
Chart: "your_top_songs_2019",
|
||||
}
|
||||
|
||||
suite.Require().NoError(d.Prepare(cfg))
|
||||
suite.NoError(d.Execute(cfg))
|
||||
}
|
||||
|
||||
func (suite *DepUpdateTestSuite) TestPrepareNamespaceFlag() {
|
||||
defer suite.ctrl.Finish()
|
||||
|
||||
cfg := Config{
|
||||
Namespace: "spotify",
|
||||
}
|
||||
|
||||
command = func(path string, args ...string) cmd {
|
||||
suite.Equal([]string{"--namespace", "spotify", "dependency", "update", "your_top_songs_2019"}, args)
|
||||
|
||||
return suite.mockCmd
|
||||
}
|
||||
suite.mockCmd.EXPECT().Stdout(gomock.Any()).AnyTimes()
|
||||
suite.mockCmd.EXPECT().Stderr(gomock.Any()).AnyTimes()
|
||||
|
||||
d := DepUpdate{
|
||||
Chart: "your_top_songs_2019",
|
||||
}
|
||||
|
||||
suite.Require().NoError(d.Prepare(cfg))
|
||||
}
|
||||
|
||||
func (suite *DepUpdateTestSuite) TestPrepareDebugFlag() {
|
||||
defer suite.ctrl.Finish()
|
||||
|
||||
stdout := strings.Builder{}
|
||||
stderr := strings.Builder{}
|
||||
cfg := Config{
|
||||
Debug: true,
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
}
|
||||
|
||||
command = func(path string, args ...string) cmd {
|
||||
suite.mockCmd.EXPECT().
|
||||
String().
|
||||
Return(fmt.Sprintf("%s %s", path, strings.Join(args, " ")))
|
||||
|
||||
return suite.mockCmd
|
||||
}
|
||||
suite.mockCmd.EXPECT().Stdout(gomock.Any()).AnyTimes()
|
||||
suite.mockCmd.EXPECT().Stderr(gomock.Any()).AnyTimes()
|
||||
|
||||
d := DepUpdate{
|
||||
Chart: "your_top_songs_2019",
|
||||
}
|
||||
|
||||
suite.Require().NoError(d.Prepare(cfg))
|
||||
|
||||
want := fmt.Sprintf("Generated command: '%s --debug dependency update your_top_songs_2019'\n", helmBin)
|
||||
suite.Equal(want, stderr.String())
|
||||
suite.Equal("", stdout.String())
|
||||
}
|
||||
|
||||
func (suite *DepUpdateTestSuite) TestPrepareChartRequired() {
|
||||
d := DepUpdate{}
|
||||
|
||||
suite.mockCmd.EXPECT().Stdout(gomock.Any()).AnyTimes()
|
||||
suite.mockCmd.EXPECT().Stderr(gomock.Any()).AnyTimes()
|
||||
|
||||
err := d.Prepare(Config{})
|
||||
suite.EqualError(err, "chart is required")
|
||||
}
|
|
@ -16,8 +16,6 @@ func (l *Lint) Execute(_ Config) error {
|
|||
}
|
||||
|
||||
// Prepare gets the Lint ready to execute.
|
||||
// Note: mandatory settings are documented in README.md, and the full list of settings is in docs/lint_settings.yml.
|
||||
// Any additions or deletions here should be reflected there.
|
||||
func (l *Lint) Prepare(cfg Config) error {
|
||||
if l.Chart == "" {
|
||||
return fmt.Errorf("chart is required")
|
||||
|
|
|
@ -25,8 +25,6 @@ func (u *Upgrade) Execute(_ Config) error {
|
|||
}
|
||||
|
||||
// Prepare gets the Upgrade ready to execute.
|
||||
// Note: mandatory settings are documented in README.md, and the full list of settings is in docs/upgrade_settings.yml.
|
||||
// Any additions or deletions here should be reflected there.
|
||||
func (u *Upgrade) Prepare(cfg Config) error {
|
||||
if u.Chart == "" {
|
||||
return fmt.Errorf("chart is required")
|
||||
|
|
Loading…
Reference in a new issue