Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat (npmExecuteScripts) enhance multi package publish from npm builds #4579

Merged
merged 17 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions cmd/artifactPrepareVersion.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,6 @@ func propagateVersion(config *artifactPrepareVersionOptions, utils artifactPrepa
}

for i, targetTool := range config.AdditionalTargetTools {
if targetTool == config.BuildTool {
// ignore configured build tool
continue
}
jliempt marked this conversation as resolved.
Show resolved Hide resolved

var buildDescriptors []string
if len(config.AdditionalTargetDescriptors) > 0 {
Expand Down
21 changes: 14 additions & 7 deletions cmd/npmExecuteScripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,21 @@ func runNpmExecuteScripts(npmExecutor npm.Executor, config *npmExecuteScriptsOpt
commonPipelineEnvironment.custom.buildSettingsInfo = buildSettingsInfo

if config.Publish {
packageJSONFiles, err := npmExecutor.FindPackageJSONFilesWithExcludes(config.BuildDescriptorExcludeList)
if err != nil {
return err
}
if len(config.BuildDescriptorList) > 0 {
err = npmExecutor.PublishAllPackages(config.BuildDescriptorList, config.RepositoryURL, config.RepositoryUsername, config.RepositoryPassword, config.PackBeforePublish)
if err != nil {
return err
}
} else {
packageJSONFiles, err := npmExecutor.FindPackageJSONFilesWithExcludes(config.BuildDescriptorExcludeList)
if err != nil {
return err
}

err = npmExecutor.PublishAllPackages(packageJSONFiles, config.RepositoryURL, config.RepositoryUsername, config.RepositoryPassword, config.PackBeforePublish)
if err != nil {
return err
err = npmExecutor.PublishAllPackages(packageJSONFiles, config.RepositoryURL, config.RepositoryUsername, config.RepositoryPassword, config.PackBeforePublish)
if err != nil {
return err
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/npmExecuteScripts_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions pkg/mock/fileUtils.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,3 +671,28 @@ func (f *FilesMock) Open(name string) (io.ReadWriteCloser, error) {
func (f *FilesMock) Create(name string) (io.ReadWriteCloser, error) {
return f.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666)
}

type FilesMockRelativeGlob struct {
*FilesMock
}

// Glob of FilesMockRelativeGlob cuts current directory path part from files if pattern is relative
func (f *FilesMockRelativeGlob) Glob(pattern string) ([]string, error) {
var matches []string
if f.files == nil {
return matches, nil
}
for path := range f.files {
if !filepath.IsAbs(pattern) {
path = strings.TrimLeft(path, f.Separator+f.CurrentDir)
}
path = strings.TrimLeft(path, f.Separator)
matched, _ := doublestar.PathMatch(pattern, path)
if matched {
matches = append(matches, path)
}
}
// The order in f.files is not deterministic, this would result in flaky tests.
sort.Strings(matches)
return matches, nil
}
46 changes: 26 additions & 20 deletions pkg/npm/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func (exec *Execute) PublishAllPackages(packageJSONFiles []string, registry, use
func (exec *Execute) publish(packageJSON, registry, username, password string, packBeforePublish bool) error {
execRunner := exec.Utils.GetExecRunner()

oldWorkingDirectory, err := exec.Utils.Getwd()

scope, err := exec.readPackageScope(packageJSON)

if err != nil {
Expand Down Expand Up @@ -130,42 +132,42 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
}

if packBeforePublish {
tmpDirectory, err := exec.Utils.TempDir(".", "temp-")

if err != nil {
return errors.Wrap(err, "creating temp directory failed")
// change directory in package json file , since npm pack will run only for that packages
if err := exec.Utils.Chdir(filepath.Dir(packageJSON)); err != nil {
return fmt.Errorf("failed to change into directory for executing script: %w", err)
}

defer exec.Utils.RemoveAll(tmpDirectory)

err = execRunner.RunExecutable("npm", "pack", "--pack-destination", tmpDirectory)
if err != nil {
if err := execRunner.RunExecutable("npm", "pack"); err != nil {
return err
}

_, err = exec.Utils.Copy(npmrc.filepath, filepath.Join(tmpDirectory, ".piperNpmrc"))
if err != nil {
return fmt.Errorf("error copying piperNpmrc file from %v to %v with error: %w",
npmrc.filepath, filepath.Join(tmpDirectory, ".piperNpmrc"), err)
}

tarballs, err := exec.Utils.Glob(filepath.Join(tmpDirectory, "*.tgz"))

tarballs, err := exec.Utils.Glob(filepath.Join(".", "*.tgz"))
if err != nil {
return err
}

if len(tarballs) != 1 {
// we do not maintain the tarball file name and hence expect only one tarball that comes
// from the npm pack command
if len(tarballs) < 1 {
return fmt.Errorf("no tarballs found")
}
if len(tarballs) > 1 {
return fmt.Errorf("found more tarballs than expected: %v", tarballs)
}

tarballFilePath, err := exec.Utils.Abs(tarballs[0])

if err != nil {
return err
}

projectNpmrc := filepath.Join(filepath.Dir(packageJSON), ".npmrc")
// if a user has a .npmrc file and if it has a scope (e.g @sap to download scoped dependencies)
// if the package to be published also has the same scope (@sap) then npm gets confused
// and tries to publish to the scope that comes from the npmrc file
// and is not the desired publish since we want to publish to the other registry (from .piperNpmrc)
// file and not to the one mentioned in the users npmrc file
// to solve this we rename the users npmrc file before publish, the original npmrc is already
// packaged in the tarball and hence renaming it before publish should not have an effect
projectNpmrc := filepath.Join(".", ".npmrc")
projectNpmrcExists, _ := exec.Utils.FileExists(projectNpmrc)

if projectNpmrcExists {
Expand All @@ -176,7 +178,7 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
}
}

err = execRunner.RunExecutable("npm", "publish", "--tarball", tarballFilePath, "--userconfig", filepath.Join(tmpDirectory, ".piperNpmrc"), "--registry", registry)
err = execRunner.RunExecutable("npm", "publish", "--tarball", tarballFilePath, "--userconfig", ".piperNpmrc", "--registry", registry)
jliempt marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return errors.Wrap(err, "failed publishing artifact")
}
Expand All @@ -188,6 +190,10 @@ func (exec *Execute) publish(packageJSON, registry, username, password string, p
log.Entry().Warnf("unable to rename the .npmrc file : %v", err)
}
}

if err := exec.Utils.Chdir(oldWorkingDirectory); err != nil {
return fmt.Errorf("failed to change back into original directory: %w", err)
}
} else {
err := execRunner.RunExecutable("npm", "publish", "--userconfig", npmrc.filepath, "--registry", registry)
if err != nil {
Expand Down
Loading