updating npm publish for #516
This commit is contained in:
parent
08b59888c9
commit
f8d5162c02
5 changed files with 133 additions and 173 deletions
|
@ -1,78 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/drone/drone/plugin/condition"
|
|
||||||
"github.com/drone/drone/shared/build/buildfile"
|
|
||||||
)
|
|
||||||
|
|
||||||
// use npm trick instead of running npm adduser that requires stdin
|
|
||||||
var npmLoginCmd = `
|
|
||||||
cat <<EOF > ~/.npmrc
|
|
||||||
_auth = $(echo "%s:%s" | tr -d "\r\n" | base64)
|
|
||||||
email = %s
|
|
||||||
EOF
|
|
||||||
`
|
|
||||||
|
|
||||||
type NPM struct {
|
|
||||||
// The Email address used by NPM to connect
|
|
||||||
// and publish to a repository
|
|
||||||
Email string `yaml:"email,omitempty"`
|
|
||||||
|
|
||||||
// The Username used by NPM to connect
|
|
||||||
// and publish to a repository
|
|
||||||
Username string `yaml:"username,omitempty"`
|
|
||||||
|
|
||||||
// The Password used by NPM to connect
|
|
||||||
// and publish to a repository
|
|
||||||
Password string `yaml:"password,omitempty"`
|
|
||||||
|
|
||||||
// Fails if the package name and version combination already
|
|
||||||
// exists in the registry. Overwrites when the "--force" flag is set.
|
|
||||||
Force bool `yaml:"force"`
|
|
||||||
|
|
||||||
// The registry URL of custom npm repository
|
|
||||||
Registry string `yaml:"registry,omitempty"`
|
|
||||||
|
|
||||||
// A folder containing the package.json file
|
|
||||||
Folder string `yaml:"folder,omitempty"`
|
|
||||||
|
|
||||||
// Registers the published package with the given tag
|
|
||||||
Tag string `yaml:"tag,omitempty"`
|
|
||||||
|
|
||||||
Condition *condition.Condition `yaml:"when,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NPM) Write(f *buildfile.Buildfile) {
|
|
||||||
|
|
||||||
if len(n.Email) == 0 || len(n.Username) == 0 || len(n.Password) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
npmPublishCmd := "npm publish %s"
|
|
||||||
|
|
||||||
if n.Tag != "" {
|
|
||||||
npmPublishCmd += fmt.Sprintf(" --tag %s", n.Tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Force {
|
|
||||||
npmPublishCmd += " --force"
|
|
||||||
}
|
|
||||||
|
|
||||||
f.WriteCmdSilent("echo 'publishing to NPM ...'")
|
|
||||||
|
|
||||||
// Login to registry
|
|
||||||
f.WriteCmdSilent(fmt.Sprintf(npmLoginCmd, n.Username, n.Password, n.Email))
|
|
||||||
|
|
||||||
// Setup custom npm registry
|
|
||||||
if n.Registry != "" {
|
|
||||||
f.WriteCmdSilent(fmt.Sprintf("npm config set registry %s", n.Registry))
|
|
||||||
}
|
|
||||||
|
|
||||||
f.WriteCmd(fmt.Sprintf(npmPublishCmd, n.Folder))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NPM) GetCondition() *condition.Condition {
|
|
||||||
return n.Condition
|
|
||||||
}
|
|
106
plugin/publish/npm/npm.go
Normal file
106
plugin/publish/npm/npm.go
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package npm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/drone/config"
|
||||||
|
"github.com/drone/drone/plugin/condition"
|
||||||
|
"github.com/drone/drone/shared/build/buildfile"
|
||||||
|
)
|
||||||
|
|
||||||
|
// command to create the .npmrc file that stores
|
||||||
|
// the login credentials, as opposed to npm login
|
||||||
|
// which requires stdin.
|
||||||
|
const CmdLogin = `
|
||||||
|
cat <<EOF > ~/.npmrc
|
||||||
|
_auth = $(echo "%s:%s" | tr -d "\r\n" | base64)
|
||||||
|
email = %s
|
||||||
|
EOF
|
||||||
|
`
|
||||||
|
|
||||||
|
const CmdPublish = "npm publish %s"
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultUser = config.String("npm-user", "")
|
||||||
|
DefaultPass = config.String("npm-pass", "")
|
||||||
|
DefaultEmail = config.String("npm-email", "")
|
||||||
|
)
|
||||||
|
|
||||||
|
type NPM struct {
|
||||||
|
// The Email address used by NPM to connect
|
||||||
|
// and publish to a repository
|
||||||
|
Email string `yaml:"email,omitempty"`
|
||||||
|
|
||||||
|
// The Username used by NPM to connect
|
||||||
|
// and publish to a repository
|
||||||
|
Username string `yaml:"username,omitempty"`
|
||||||
|
|
||||||
|
// The Password used by NPM to connect
|
||||||
|
// and publish to a repository
|
||||||
|
Password string `yaml:"password,omitempty"`
|
||||||
|
|
||||||
|
// Fails if the package name and version combination already
|
||||||
|
// exists in the registry. Overwrites when the "--force" flag is set.
|
||||||
|
Force bool `yaml:"force"`
|
||||||
|
|
||||||
|
// The registry URL of custom npm repository
|
||||||
|
Registry string `yaml:"registry,omitempty"`
|
||||||
|
|
||||||
|
// A folder containing the package.json file
|
||||||
|
Folder string `yaml:"folder,omitempty"`
|
||||||
|
|
||||||
|
// Registers the published package with the given tag
|
||||||
|
Tag string `yaml:"tag,omitempty"`
|
||||||
|
|
||||||
|
// Force npm to always require authentication when accessing the registry.
|
||||||
|
AlwaysAuth bool `yaml:"always_auth"`
|
||||||
|
|
||||||
|
Condition *condition.Condition `yaml:"when,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NPM) Write(f *buildfile.Buildfile) {
|
||||||
|
// If the yaml doesn't provide a username or password
|
||||||
|
// we should attempt to use the global defaults.
|
||||||
|
if len(n.Email) == 0 {
|
||||||
|
n.Username = *DefaultUser
|
||||||
|
n.Password = *DefaultPass
|
||||||
|
n.Email = *DefaultEmail
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the yaml doesn't provide a username or password,
|
||||||
|
// and there was not global configuration defined, EXIT.
|
||||||
|
if len(n.Email) == 0 ||
|
||||||
|
len(n.Username) == 0 ||
|
||||||
|
len(n.Password) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd = CmdPublish
|
||||||
|
|
||||||
|
if len(n.Tag) != 0 {
|
||||||
|
cmd += fmt.Sprintf(" --tag %s", n.Tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.Force {
|
||||||
|
cmd += " --force"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the npm credentials
|
||||||
|
f.WriteCmdSilent(fmt.Sprintf(CmdLogin, n.Username, n.Password, n.Email))
|
||||||
|
|
||||||
|
// Setup custom npm registry
|
||||||
|
if len(n.Registry) != 0 {
|
||||||
|
f.WriteCmd(fmt.Sprintf("npm config set registry %s", n.Registry))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set npm to always authenticate
|
||||||
|
if n.AlwaysAuth {
|
||||||
|
f.WriteCmd("npm set always-auth true")
|
||||||
|
}
|
||||||
|
|
||||||
|
f.WriteCmd(fmt.Sprintf(cmd, n.Folder))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NPM) GetCondition() *condition.Condition {
|
||||||
|
return n.Condition
|
||||||
|
}
|
22
plugin/publish/npm/npm_test.go
Normal file
22
plugin/publish/npm/npm_test.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package npm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/franela/goblin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_NPM(t *testing.T) {
|
||||||
|
|
||||||
|
g := goblin.Goblin(t)
|
||||||
|
g.Describe("NPM Publish", func() {
|
||||||
|
g.It("Should set force")
|
||||||
|
g.It("Should set tag")
|
||||||
|
g.It("Should set registry")
|
||||||
|
g.It("Should set always-auth")
|
||||||
|
g.It("Should run publish")
|
||||||
|
g.It("Should create npmrc")
|
||||||
|
g.It("Should fail when no username or password")
|
||||||
|
g.It("Should use default username or password")
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,91 +0,0 @@
|
||||||
package publish
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/drone/drone/shared/build/buildfile"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// emulate Build struct
|
|
||||||
type PublishToNPM struct {
|
|
||||||
Publish *Publish `yaml:"publish,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var sampleYml1 = `
|
|
||||||
publish:
|
|
||||||
npm:
|
|
||||||
username: foo
|
|
||||||
email: foo@example.com
|
|
||||||
password: bar
|
|
||||||
`
|
|
||||||
|
|
||||||
var sampleYml2 = `
|
|
||||||
publish:
|
|
||||||
npm:
|
|
||||||
username: foo
|
|
||||||
email: foo@example.com
|
|
||||||
password: bar
|
|
||||||
force: true
|
|
||||||
`
|
|
||||||
|
|
||||||
var sampleYmlWithReg = `
|
|
||||||
publish:
|
|
||||||
npm:
|
|
||||||
username: foo
|
|
||||||
email: foo@example.com
|
|
||||||
password: bar
|
|
||||||
registry: https://npm.example.com/me/
|
|
||||||
folder: my-project/node-app/
|
|
||||||
tag: 1.2.3
|
|
||||||
`
|
|
||||||
|
|
||||||
func setUpWithNPM(input string) (string, error) {
|
|
||||||
var buildStruct PublishToNPM
|
|
||||||
err := yaml.Unmarshal([]byte(input), &buildStruct)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
bf := buildfile.New()
|
|
||||||
buildStruct.Publish.Write(bf, nil)
|
|
||||||
return bf.String(), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNPMPublish(t *testing.T) {
|
|
||||||
bscr, err := setUpWithNPM(sampleYml1)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Can't unmarshal publish script: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(bscr, "npm publish") {
|
|
||||||
t.Error("Expect script to contain install command")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNPMForcePublish(t *testing.T) {
|
|
||||||
bscr, err := setUpWithNPM(sampleYml2)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Can't unmarshal publish script: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(bscr, "npm publish --force") {
|
|
||||||
t.Error("Expect script to contain install command")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNPMPublishRegistry(t *testing.T) {
|
|
||||||
bscr, err := setUpWithNPM(sampleYmlWithReg)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Can't unmarshal publish script: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(bscr, "npm config set registry https://npm.example.com/me/") {
|
|
||||||
t.Error("Expect script to contain npm config registry command")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(bscr, "npm publish my-project/node-app/ --tag 1.2.3") {
|
|
||||||
t.Error("Expect script to contain npm publish command")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package publish
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/drone/drone/plugin/condition"
|
"github.com/drone/drone/plugin/condition"
|
||||||
|
"github.com/drone/drone/plugin/publish/npm"
|
||||||
"github.com/drone/drone/shared/build/buildfile"
|
"github.com/drone/drone/shared/build/buildfile"
|
||||||
"github.com/drone/drone/shared/build/repo"
|
"github.com/drone/drone/shared/build/repo"
|
||||||
)
|
)
|
||||||
|
@ -10,10 +11,10 @@ import (
|
||||||
// for publishing build artifacts when
|
// for publishing build artifacts when
|
||||||
// a Build has succeeded
|
// a Build has succeeded
|
||||||
type Publish struct {
|
type Publish struct {
|
||||||
S3 *S3 `yaml:"s3,omitempty"`
|
S3 *S3 `yaml:"s3,omitempty"`
|
||||||
Swift *Swift `yaml:"swift,omitempty"`
|
Swift *Swift `yaml:"swift,omitempty"`
|
||||||
PyPI *PyPI `yaml:"pypi,omitempty"`
|
PyPI *PyPI `yaml:"pypi,omitempty"`
|
||||||
NPM *NPM `yaml:"npm,omitempty"`
|
NPM *npm.NPM `yaml:"npm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Publish) Write(f *buildfile.Buildfile, r *repo.Repo) {
|
func (p *Publish) Write(f *buildfile.Buildfile, r *repo.Repo) {
|
||||||
|
|
Loading…
Reference in a new issue