Skip to content

Commit 739ce0d

Browse files
authored
feat(sidekick): allow skipping semver checks for rust-publish (#2584)
Running `cargo semver-checks` takes hours to run. This makes testing the release process difficult. Add a flag to skip the checks to make it easier to test later parts of the release process. For #2514
1 parent b3cb3df commit 739ce0d

File tree

3 files changed

+74
-21
lines changed

3 files changed

+74
-21
lines changed

internal/sidekick/internal/rust_release/publish.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ import (
2828
"github.com/googleapis/librarian/internal/sidekick/internal/external"
2929
)
3030

31-
// Publish finds all the crates that should be published, runs
31+
// Publish finds all the crates that should be published, (optionally) runs
3232
// `cargo semver-checks` and (optionally) publishes them.
33-
func Publish(config *config.Release, dryRun bool) error {
33+
func Publish(config *config.Release, dryRun bool, skipSemverChecks bool) error {
3434
if err := PreFlight(config); err != nil {
3535
return err
3636
}
@@ -74,13 +74,15 @@ func Publish(config *config.Release, dryRun bool) error {
7474
return fmt.Errorf("mismatched workspace plan vs. changed crates, probably missing some version bumps (-plan, +changed):\n%s", diff)
7575
}
7676

77-
for name, manifest := range manifests {
78-
if isNewFile(config, lastTag, manifest) {
79-
continue
80-
}
81-
slog.Info("runnning cargo semver-checks to detect breaking changes", "crate", name)
82-
if err := external.Run(cargoExe(config), "semver-checks", "--all-features", "-p", name); err != nil {
83-
return err
77+
if !skipSemverChecks {
78+
for name, manifest := range manifests {
79+
if isNewFile(config, lastTag, manifest) {
80+
continue
81+
}
82+
slog.Info("runnning cargo semver-checks to detect breaking changes", "crate", name)
83+
if err := external.Run(cargoExe(config), "semver-checks", "--all-features", "-p", name); err != nil {
84+
return err
85+
}
8486
}
8587
}
8688
slog.Info("publishing crates with: cargo workspaces publish --skip-published ...")

internal/sidekick/internal/rust_release/publish_test.go

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package rustrelease
1717
import (
1818
"os"
1919
"path"
20+
"runtime"
2021
"testing"
2122

2223
"github.com/googleapis/librarian/internal/sidekick/internal/config"
@@ -42,7 +43,7 @@ func TestPublishSuccess(t *testing.T) {
4243
}
4344
remoteDir := setupForPublish(t, "release-2001-02-03")
4445
cloneRepository(t, remoteDir)
45-
if err := Publish(config, true); err != nil {
46+
if err := Publish(config, true, false); err != nil {
4647
t.Fatal(err)
4748
}
4849
}
@@ -73,7 +74,7 @@ func TestPublishWithNewCrate(t *testing.T) {
7374
t.Fatal(err)
7475
}
7576
cloneRepository(t, remoteDir)
76-
if err := Publish(config, true); err != nil {
77+
if err := Publish(config, true, false); err != nil {
7778
t.Fatal(err)
7879
}
7980
}
@@ -103,7 +104,7 @@ func TestPublishWithRootsPem(t *testing.T) {
103104
}
104105
remoteDir := setupForPublish(t, "release-with-roots-pem")
105106
cloneRepository(t, remoteDir)
106-
if err := Publish(config, true); err != nil {
107+
if err := Publish(config, true, false); err != nil {
107108
t.Fatal(err)
108109
}
109110
}
@@ -134,7 +135,7 @@ func TestPublishWithLocalChangesError(t *testing.T) {
134135
if err := external.Run("git", "commit", "-m", "feat: created pubsub", "."); err != nil {
135136
t.Fatal(err)
136137
}
137-
if err := Publish(config, true); err == nil {
138+
if err := Publish(config, true, false); err == nil {
138139
t.Errorf("expected an error publishing a dirty local repository")
139140
}
140141
}
@@ -145,7 +146,7 @@ func TestPublishPreflightError(t *testing.T) {
145146
"git": "git-not-found",
146147
},
147148
}
148-
if err := Publish(config, true); err == nil {
149+
if err := Publish(config, true, false); err == nil {
149150
t.Errorf("expected an error in BumpVersions() with a bad git command")
150151
}
151152
}
@@ -163,7 +164,7 @@ func TestPublishLastTagError(t *testing.T) {
163164
}
164165
remoteDir := setupForPublish(t, "release-2001-02-03")
165166
cloneRepository(t, remoteDir)
166-
if err := Publish(&config, true); err == nil {
167+
if err := Publish(&config, true, false); err == nil {
167168
t.Fatalf("expected an error during GetLastTag")
168169
}
169170
}
@@ -198,7 +199,7 @@ func TestPublishBadManifest(t *testing.T) {
198199
t.Fatal(err)
199200
}
200201
cloneRepository(t, remoteDir)
201-
if err := Publish(config, true); err == nil {
202+
if err := Publish(config, true, false); err == nil {
202203
t.Errorf("expected an error with a bad manifest file")
203204
}
204205
}
@@ -215,7 +216,7 @@ func TestPublishGetPlanError(t *testing.T) {
215216
}
216217
remoteDir := setupForPublish(t, "release-2001-02-03")
217218
cloneRepository(t, remoteDir)
218-
if err := Publish(config, true); err == nil {
219+
if err := Publish(config, true, false); err == nil {
219220
t.Fatalf("expected an error during plan generation")
220221
}
221222
}
@@ -239,7 +240,52 @@ func TestPublishPlanMismatchError(t *testing.T) {
239240
}
240241
remoteDir := setupForPublish(t, "release-2001-02-03")
241242
cloneRepository(t, remoteDir)
242-
if err := Publish(config, true); err == nil {
243+
if err := Publish(config, true, false); err == nil {
243244
t.Fatalf("expected an error during plan comparison")
244245
}
245246
}
247+
248+
func TestPublishSkipSemverChecks(t *testing.T) {
249+
if runtime.GOOS == "windows" {
250+
t.Skip("skipping on windows, bash script set up does not work")
251+
}
252+
253+
requireCommand(t, "git")
254+
requireCommand(t, "/bin/echo")
255+
tmpDir := t.TempDir()
256+
// Create a fake cargo that fails on `semver-checks`
257+
cargoScript := path.Join(tmpDir, "cargo")
258+
script := `#!/bin/bash
259+
if [ "$1" == "semver-checks" ]; then
260+
exit 1
261+
elif [ "$1" == "workspaces" ] && [ "$2" == "plan" ]; then
262+
echo "google-cloud-storage"
263+
else
264+
/bin/echo $@
265+
fi
266+
`
267+
if err := os.WriteFile(cargoScript, []byte(script), 0755); err != nil {
268+
t.Fatal(err)
269+
}
270+
271+
config := &config.Release{
272+
Remote: "origin",
273+
Branch: "main",
274+
Preinstalled: map[string]string{
275+
"git": "git",
276+
"cargo": cargoScript,
277+
},
278+
}
279+
remoteDir := setupForPublish(t, "release-2001-02-03")
280+
cloneRepository(t, remoteDir)
281+
282+
// This should fail because semver-checks fails.
283+
if err := Publish(config, true, false); err == nil {
284+
t.Fatal("expected an error from semver-checks")
285+
}
286+
287+
// Skipping the checks should succeed.
288+
if err := Publish(config, true, true); err != nil {
289+
t.Fatal(err)
290+
}
291+
}

internal/sidekick/rust_publish.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import (
1919
rustrelease "github.com/googleapis/librarian/internal/sidekick/internal/rust_release"
2020
)
2121

22+
var (
23+
skipSemverChecks bool
24+
)
25+
2226
func init() {
2327
newCommand(
2428
"sidekick rust-publish",
@@ -32,10 +36,11 @@ the dependency order.
3236
`,
3337
cmdSidekick,
3438
rustPublish,
35-
)
39+
).addFlagBool(&skipSemverChecks, "skip-semver-checks", false, "skip 'cargo semver-checks' for changed crates.")
3640
}
3741

38-
// rustBumpVersions increments the version numbers as needed.
42+
// rustPublish finds all the crates that should be published, (optionally) runs
43+
// `cargo semver-checks` and (optionally) publishes them.
3944
func rustPublish(rootConfig *config.Config, cmdLine *CommandLine) error {
40-
return rustrelease.Publish(rootConfig.Release, cmdLine.DryRun)
45+
return rustrelease.Publish(rootConfig.Release, cmdLine.DryRun, skipSemverChecks)
4146
}

0 commit comments

Comments
 (0)