Skip to content

Commit

Permalink
feat (npmExecuteScripts) enhance multi package publish from npm builds (
Browse files Browse the repository at this point in the history
SAP#4579)

* enabling publish to only publish sub packages

* changing directory and then coming back to original after the publish runs

* searching the glob tar and npmrc in the current directory

* excluding build descriptor check and addtional target tool check

* changing the npm pack before publish to run only in sub packages

* removing commented code clean up

* adding the correct npm pack

* improve logging

* fix error handling and a bit style fix

* fix unit tests

* remove commented lines

* respecting build descriptor list when provided

* improve docu for the step param

* fixing linting issues

* improve docu

---------

Co-authored-by: Gulom Alimov <[email protected]>
Co-authored-by: Jordi van Liempt <[email protected]>
  • Loading branch information
3 people authored and daskuznetsova committed Oct 13, 2023
1 parent 9a00fa2 commit 0f8b26f
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 79 deletions.
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
}

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)
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

0 comments on commit 0f8b26f

Please sign in to comment.