44package release
55
66import (
7+ "errors"
78 "fmt"
89 "log"
10+ "path"
11+ "strings"
912 "time"
1013
14+ "github.com/Azure/azure-sdk-for-go/eng/tools/generator/cmd/issue/link"
1115 "github.com/Azure/azure-sdk-for-go/eng/tools/generator/cmd/v2/common"
16+ "github.com/Azure/azure-sdk-for-go/eng/tools/generator/config"
17+ "github.com/Azure/azure-sdk-for-go/eng/tools/generator/config/validate"
1218 "github.com/Azure/azure-sdk-for-go/eng/tools/generator/flags"
19+ "github.com/Azure/azure-sdk-for-go/eng/tools/generator/repo"
20+ "github.com/go-git/go-git/v5/plumbing"
1321 "github.com/spf13/cobra"
1422 "github.com/spf13/pflag"
1523)
1624
1725var (
1826 releaseBranchNamePattern = "release-%s-%s-%s-%v"
27+ confirmComment = "Release [PR](%s) is ready. Please check whether the package works well ([doc for testing with the generated Go SDK](https://github.com/Azure/azure-rest-api-specs/blob/main/documentation/code-gen/configure-go-sdk.md#test-with-the-generated-go-sdk)). If you are not a Golang user, you can mainly check whether the changelog meets your requirements."
1928)
2029
2130// Release command
2231func Command () * cobra.Command {
2332 releaseCmd := & cobra.Command {
24- Use : "release-v2 <azure-sdk-for-go directory/commitid> <azure-rest-api-specs directory/commitid> <rp-name> [namespaceName]" ,
33+ Use : "release-v2 <azure-sdk-for-go directory/commitid> <azure-rest-api-specs directory/commitid> <rp-name/release-request-json-config > [namespaceName]" ,
2534 Short : "Generate a v2 release of azure-sdk-for-go" ,
2635 Long : `This command will generate a new v2 release for azure-sdk-for-go with given rp name and namespace name.
2736
2837azure-sdk-for-go directory/commitid: the directory path of the azure-sdk-for-go with git control or just a commitid for remote repo
2938azure-rest-api-specs directory: the directory path of the azure-rest-api-specs with git control or just a commitid for remote repo
30- rp-name: name of resource provider to be released, same for the swagger folder name
39+ rp-name/release-request-json-config : name of resource provider to be released ( same for the swagger folder name) or release request json config file path generated by 'generator issue'
3140namespaceName: name of namespace to be released, default value is arm+rp-name
3241
3342` ,
@@ -64,6 +73,7 @@ type Flags struct {
6473 SkipGenerateExample bool
6574 PackageConfig string
6675 GoVersion string
76+ Token string
6777}
6878
6979func BindFlags (flagSet * pflag.FlagSet ) {
@@ -77,6 +87,7 @@ func BindFlags(flagSet *pflag.FlagSet) {
7787 flagSet .Bool ("skip-generate-example" , false , "Skip generate example for SDK in the same time" )
7888 flagSet .String ("package-config" , "" , "Additional config for package" )
7989 flagSet .String ("go-version" , "1.18" , "Go version" )
90+ flagSet .StringP ("token" , "t" , "" , "Specify the personal access token of Github" )
8091}
8192
8293func ParseFlags (flagSet * pflag.FlagSet ) Flags {
@@ -91,6 +102,7 @@ func ParseFlags(flagSet *pflag.FlagSet) Flags {
91102 SkipGenerateExample : flags .GetBool (flagSet , "skip-generate-example" ),
92103 PackageConfig : flags .GetString (flagSet , "package-config" ),
93104 GoVersion : flags .GetString (flagSet , "go-version" ),
105+ Token : flags .GetString (flagSet , "token" ),
94106 }
95107}
96108
@@ -111,6 +123,14 @@ func (c *commandContext) execute(sdkRepoParam, specRepoParam string) error {
111123 return err
112124 }
113125
126+ if path .Ext (c .rpName ) == ".json" {
127+ return c .generateFromRequest (sdkRepo , specRepoParam , specCommitHash )
128+ } else {
129+ return c .generate (sdkRepo , specCommitHash )
130+ }
131+ }
132+
133+ func (c * commandContext ) generate (sdkRepo repo.SDKRepository , specCommitHash string ) error {
114134 log .Printf ("Release generation for rp: %s, namespace: %s" , c .rpName , c .namespaceName )
115135 generateCtx := common.GenerateContext {
116136 SDKPath : sdkRepo .Root (),
@@ -155,3 +175,103 @@ func (c *commandContext) execute(sdkRepoParam, specRepoParam string) error {
155175
156176 return nil
157177}
178+
179+ func (c * commandContext ) generateFromRequest (sdkRepo repo.SDKRepository , specRepoParam , specCommitHash string ) error {
180+ var pullRequestUrls = make (map [string ]string )
181+ var pushBranch = make (map [string ]string )
182+ forkRemote , err := repo .GetForkRemote (sdkRepo )
183+ if err != nil {
184+ return err
185+ }
186+
187+ log .Printf ("track2 parsing the config..." )
188+ cfg , err := config .ParseConfig (c .rpName )
189+ if err != nil {
190+ return fmt .Errorf ("parse config err: %v" , err )
191+ }
192+ log .Printf ("Configuration: %s" , cfg .String ())
193+ armServices , err := validate .ParseTrack2 (cfg , specRepoParam )
194+ if err != nil {
195+ return err
196+ }
197+ for arm , packageInfos := range armServices {
198+ for _ , info := range packageInfos {
199+ originalHead , err := sdkRepo .Head ()
200+ if err != nil {
201+ return err
202+ }
203+
204+ // run generator
205+ c .rpName = arm
206+ c .namespaceName = info .Name
207+ c .flags .SpecRPName = info .SpecName
208+ err = c .generate (sdkRepo , specCommitHash )
209+ if err != nil {
210+ return err
211+ }
212+
213+ // get current branch name
214+ generateHead , err := sdkRepo .Head ()
215+ if err != nil {
216+ return err
217+ }
218+ pushBranch [generateHead .Name ().Short ()] = info .RequestLink
219+
220+ log .Printf ("git checkout %v" , originalHead .Name ().Short ())
221+ if err := sdkRepo .Checkout (& repo.CheckoutOptions {
222+ Branch : plumbing .ReferenceName (originalHead .Name ().Short ()),
223+ Force : true ,
224+ }); err != nil {
225+ return err
226+ }
227+ }
228+ }
229+
230+ for branch := range pushBranch {
231+ log .Printf ("Fixes: %s\n " , branch )
232+ }
233+
234+ if c .flags .Token != "" {
235+ for branchName , issue := range pushBranch {
236+ log .Printf ("git push fork %s\n " , branchName )
237+ msg , err := common .ExecuteGitPush (sdkRepo .Root (), forkRemote .Config ().Name , branchName )
238+ if err != nil {
239+ return fmt .Errorf ("git push fork error:%v,msg:%s" , err , msg )
240+ }
241+
242+ githubUserName := repo .GetRemoteUserName (forkRemote )
243+ if githubUserName == "" {
244+ return errors .New ("github user name not exist" )
245+ }
246+
247+ log .Printf ("%s: create pull request...\n " , branchName )
248+ pullRequestUrl , err := common .ExecuteCreatePullRequest (sdkRepo .Root (), link .SpecOwner , link .SDKRepo , githubUserName , branchName , repo .ReleaseTitle (branchName ), issue , c .flags .Token )
249+ if err != nil {
250+ return err
251+ }
252+ pullRequestUrls [branchName ] = pullRequestUrl
253+
254+ log .Printf ("Leave a comment in %s...\n " , issue )
255+ issueNumber := strings .Split (issue , "/" )
256+ err = common .ExecuteAddIssueComment (sdkRepo .Root (), link .SpecOwner , link .ReleaseIssueRepo , issueNumber [len (issueNumber )- 1 ], fmt .Sprintf (confirmComment , pullRequestUrl ), c .flags .Token )
257+ if err != nil {
258+ return err
259+ }
260+
261+ log .Printf ("Add Labels...\n " )
262+ err = common .ExecuteAddIssueLabels (sdkRepo .Root (), link .SpecOwner , link .ReleaseIssueRepo , issueNumber [len (issueNumber )- 1 ], c .flags .Token , []string {"PRready" })
263+ if err != nil {
264+ return err
265+ }
266+ }
267+ }
268+
269+ if len (pullRequestUrls ) != 0 {
270+ log .Println ("Fixes:" )
271+ for branch , url := range pullRequestUrls {
272+ log .Printf ("%s : %s" , branch , url )
273+ }
274+ }
275+
276+ return nil
277+ }
0 commit comments