github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/ci/release/github.go (about)

     1  /*
     2   * Copyright (C) 2019 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package release
    19  
    20  import (
    21  	"fmt"
    22  	"os"
    23  	"path"
    24  	"time"
    25  
    26  	"github.com/mysteriumnetwork/go-ci/job"
    27  	"github.com/pkg/errors"
    28  	"github.com/rs/zerolog/log"
    29  
    30  	gogithub "github.com/google/go-github/v28/github"
    31  	"github.com/mysteriumnetwork/go-ci/env"
    32  	"github.com/mysteriumnetwork/go-ci/github"
    33  	"github.com/mysteriumnetwork/node/ci/storage"
    34  	"github.com/mysteriumnetwork/node/logconfig"
    35  )
    36  
    37  type releaseGithubOpts struct {
    38  	owner      string
    39  	repository string
    40  	version    string
    41  	token      string
    42  	createTag  bool
    43  }
    44  
    45  // release releases build/package files to github
    46  func releaseGithub(opts *releaseGithubOpts) error {
    47  	if err := storage.DownloadArtifacts(); err != nil {
    48  		return err
    49  	}
    50  
    51  	release, err := tagReleaseGithub(opts)
    52  	if err != nil {
    53  		return err
    54  	}
    55  
    56  	artifactFilenames, err := os.ReadDir("build/package")
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	for _, f := range artifactFilenames {
    62  		p := path.Join("build/package", f.Name())
    63  		err := release.UploadAsset(p)
    64  		var githubErr *gogithub.ErrorResponse
    65  		if errors.As(err, &githubErr) && len(githubErr.Errors) == 1 && githubErr.Errors[0].Code == "already_exists" {
    66  			log.Info().Msg("Release artifact already exists: " + f.Name())
    67  			continue
    68  		}
    69  		if err != nil {
    70  			return errors.Wrap(err, "could not upload artifact "+p)
    71  		}
    72  	}
    73  
    74  	log.Info().Msg("Artifacts uploaded successfully")
    75  	return nil
    76  }
    77  
    78  func tagReleaseGithub(opts *releaseGithubOpts) (*github.Release, error) {
    79  	releaser, err := github.NewReleaser(opts.owner, opts.repository, opts.token)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	if opts.createTag {
    85  		return releaser.Create(opts.version)
    86  	}
    87  
    88  	return releaser.Find(opts.version)
    89  }
    90  
    91  // ReleaseGithubSnapshot releases snapshot to github
    92  func ReleaseGithubSnapshot() error {
    93  	logconfig.Bootstrap()
    94  
    95  	if err := env.EnsureEnvVars(
    96  		env.SnapshotBuild,
    97  		env.GithubOwner,
    98  		env.GithubSnapshotRepository,
    99  		env.BuildVersion,
   100  		env.GithubAPIToken,
   101  	); err != nil {
   102  		return err
   103  	}
   104  	job.Precondition(func() bool {
   105  		return env.Bool(env.SnapshotBuild)
   106  	})
   107  
   108  	return releaseGithub(&releaseGithubOpts{
   109  		owner:      env.Str(env.GithubOwner),
   110  		repository: env.Str(env.GithubSnapshotRepository),
   111  		version:    env.Str(env.BuildVersion),
   112  		token:      env.Str(env.GithubAPIToken),
   113  		createTag:  true,
   114  	})
   115  }
   116  
   117  // ReleaseGithubNightly releases nightly artifacts to github
   118  func ReleaseGithubNightly() error {
   119  	logconfig.Bootstrap()
   120  
   121  	if err := env.EnsureEnvVars(
   122  		env.GithubOwner,
   123  		env.BuildVersion,
   124  		env.GithubAPIToken,
   125  	); err != nil {
   126  		return err
   127  	}
   128  	job.Precondition(func() bool {
   129  		return env.Bool("NIGHTLY_BUILD")
   130  	})
   131  
   132  	return releaseGithub(&releaseGithubOpts{
   133  		owner:      env.Str(env.GithubOwner),
   134  		repository: "nightly",
   135  		version:    fmt.Sprintf("nightly-%s", time.Now().Format("20060102")),
   136  		token:      env.Str(env.GithubAPIToken),
   137  		createTag:  true,
   138  	})
   139  }
   140  
   141  // ReleaseGithubTag releases tag to github
   142  func ReleaseGithubTag() error {
   143  	logconfig.Bootstrap()
   144  
   145  	if err := env.EnsureEnvVars(
   146  		env.SnapshotBuild,
   147  		env.GithubOwner,
   148  		env.GithubRepository,
   149  		env.BuildVersion,
   150  		env.GithubAPIToken,
   151  	); err != nil {
   152  		return err
   153  	}
   154  	job.Precondition(func() bool {
   155  		return env.Bool(env.TagBuild)
   156  	})
   157  
   158  	err := releaseGithub(&releaseGithubOpts{
   159  		owner:      env.Str(env.GithubOwner),
   160  		repository: env.Str(env.GithubRepository),
   161  		version:    env.Str(env.BuildVersion),
   162  		token:      env.Str(env.GithubAPIToken),
   163  		createTag:  false, // Tag is already created manually - which is release process trigger
   164  	})
   165  	if err != nil {
   166  		return err
   167  	}
   168  
   169  	_, err = tagReleaseGithub(&releaseGithubOpts{
   170  		owner:      env.Str(env.GithubOwner),
   171  		repository: "mysterium-client-npm-package",
   172  		version:    env.Str(env.BuildVersion),
   173  		token:      env.Str(env.GithubAPIToken),
   174  		createTag:  true, // Tag the related project to release artifacts in another repo
   175  	})
   176  	return err
   177  }