Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions pkg/app/api/grpcapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func (a *API) SyncApplication(ctx context.Context, req *apiservice.SyncApplicati
Commander: key.Id,
SyncApplication: &model.Command_SyncApplication{
ApplicationId: app.Id,
SyncStrategy: model.SyncStrategy_NONE,
},
}
if err := addCommand(ctx, a.commandStore, &cmd, a.logger); err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/app/api/grpcapi/web_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ func (a *WebAPI) SyncApplication(ctx context.Context, req *webservice.SyncApplic
Commander: claims.Subject,
SyncApplication: &model.Command_SyncApplication{
ApplicationId: app.Id,
SyncStrategy: req.SyncStrategy,
},
}
if err := addCommand(ctx, a.commandStore, &cmd, a.logger); err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/app/api/service/webservice/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ message ListApplicationsResponse {

message SyncApplicationRequest {
string application_id = 1 [(validate.rules).string.min_len = 1];
model.SyncStrategy sync_strategy = 2;
}

message SyncApplicationResponse {
Expand Down
23 changes: 20 additions & 3 deletions pkg/app/piped/planner/cloudrun/cloudrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,28 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
in.Logger.Warn("unable to determine target version", zap.Error(e))
}

// If the deployment was triggered by forcing via web UI,
// we rely on the user's decision.
switch in.Deployment.Trigger.SyncStrategy {
case model.SyncStrategy_QUICK_SYNC:
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = fmt.Sprintf("Quick sync to deploy image %s and configure all traffic to it (forced via web)", out.Version)
return
case model.SyncStrategy_PIPELINE:
if cfg.Pipeline == nil {
err = fmt.Errorf("unable to force sync with pipeline because no pipeline was specified")
return
}
out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now())
out.Summary = fmt.Sprintf("Sync with pipeline to deploy image %s (forced via web)", out.Version)
return
}

// This is the first time to deploy this application or it was unable to retrieve that value.
// We just do the quick sync.
if in.MostRecentSuccessfulCommitHash == "" {
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = fmt.Sprintf("Quick sync to deploy image %s and configure all traffic to it because it seems this is the first deployment", out.Version)
out.Summary = fmt.Sprintf("Quick sync to deploy image %s and configure all traffic to it (it seems this is the first deployment)", out.Version)
return
}

Expand All @@ -82,13 +99,13 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
if err == nil {
if lastVersion, e := p.determineVersion(ds.AppDir, cfg.Input.ServiceManifestFile); e == nil {
out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now())
out.Summary = fmt.Sprintf("Sync progressively to update image from %s to %s", lastVersion, out.Version)
out.Summary = fmt.Sprintf("Sync with pipeline to update image from %s to %s", lastVersion, out.Version)
return
}
}

out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now())
out.Summary = "Sync progressively with the specified pipeline"
out.Summary = "Sync with the specified pipeline"
return
}

Expand Down
25 changes: 21 additions & 4 deletions pkg/app/piped/planner/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,27 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
out.Version = version
}

// If the deployment was triggered by forcing via web UI,
// we rely on the user's decision.
switch in.Deployment.Trigger.SyncStrategy {
case model.SyncStrategy_QUICK_SYNC:
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = fmt.Sprintf("Quick sync by applying all manifests (forced via web)", out.Version)
return
case model.SyncStrategy_PIPELINE:
if cfg.Pipeline == nil {
err = fmt.Errorf("unable to force sync with pipeline because no pipeline was specified")
return
}
out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now())
out.Summary = "Sync with the specified pipeline (forced via web)"
return
}

// If the progressive pipeline was not configured
// we have only one choise to do is applying all manifestt.
if cfg.Pipeline == nil || len(cfg.Pipeline.Stages) == 0 {
out.Stages = buildPipeline(cfg.Input.AutoRollback, time.Now())
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = "Quick sync by applying all manifests (no pipeline was configured)"
return
}
Expand Down Expand Up @@ -120,7 +137,7 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
return out, err
}
if syncRegex.MatchString(in.Deployment.Trigger.Commit.Message) {
out.Stages = buildPipeline(cfg.Input.AutoRollback, time.Now())
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = fmt.Sprintf("Quick sync by applying all manifests because the commit message was matching %q", s)
return out, err
}
Expand All @@ -130,7 +147,7 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
// or it was unable to retrieve that value.
// We just apply all manifests.
if in.MostRecentSuccessfulCommitHash == "" {
out.Stages = buildPipeline(cfg.Input.AutoRollback, time.Now())
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = "Quick sync by applying all manifests because it seems this is the first deployment"
return
}
Expand Down Expand Up @@ -163,7 +180,7 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
return
}

out.Stages = buildPipeline(cfg.Input.AutoRollback, time.Now())
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
return
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/app/piped/planner/kubernetes/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/pipe-cd/pipe/pkg/model"
)

func buildPipeline(autoRollback bool, now time.Time) []*model.PipelineStage {
func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineStage {
var (
preStageID = ""
stage, _ = planner.GetPredefinedStage(planner.PredefinedStageK8sSync)
Expand Down
4 changes: 2 additions & 2 deletions pkg/app/piped/planner/kubernetes/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/pipe-cd/pipe/pkg/model"
)

func TestBuildPipeline(t *testing.T) {
func TestBuildQuickSyncPipeline(t *testing.T) {
tests := []struct {
name string
wantAutoRollback bool
Expand All @@ -26,7 +26,7 @@ func TestBuildPipeline(t *testing.T) {
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
gotStages := buildPipeline(tc.wantAutoRollback, time.Now())
gotStages := buildQuickSyncPipeline(tc.wantAutoRollback, time.Now())
var gotAutoRollback bool
for _, stage := range gotStages {
if stage.Name == string(model.StageRollback) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/piped/planner/terraform/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/pipe-cd/pipe/pkg/model"
)

func builQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineStage {
func buildQuickSyncPipeline(autoRollback bool, now time.Time) []*model.PipelineStage {
var (
s, _ = planner.GetPredefinedStage(planner.PredefinedStageTerraformSync)
out = make([]*model.PipelineStage, 0, 2)
Expand Down
19 changes: 18 additions & 1 deletion pkg/app/piped/planner/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,28 @@ func (p *Planner) Plan(ctx context.Context, in planner.Input) (out planner.Outpu
return
}

// If the deployment was triggered by forcing via web UI,
// we rely on the user's decision.
switch in.Deployment.Trigger.SyncStrategy {
case model.SyncStrategy_QUICK_SYNC:
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, time.Now())
out.Summary = "Quick sync by automatically applying any detected changes because no pipeline was configured (forced via web)"
return
case model.SyncStrategy_PIPELINE:
if cfg.Pipeline == nil {
err = fmt.Errorf("unable to force sync with pipeline because no pipeline was specified")
return
}
out.Stages = buildProgressivePipeline(cfg.Pipeline, cfg.Input.AutoRollback, time.Now())
out.Summary = "Sync with the specified progressive pipeline (forced via web)"
return
}

now := time.Now()
out.Version = "N/A"

if cfg.Pipeline == nil || len(cfg.Pipeline.Stages) == 0 {
out.Stages = builQuickSyncPipeline(cfg.Input.AutoRollback, now)
out.Stages = buildQuickSyncPipeline(cfg.Input.AutoRollback, now)
out.Summary = "Quick sync by automatically applying any detected changes because no pipeline was configured"
return
}
Expand Down
25 changes: 20 additions & 5 deletions pkg/app/piped/trigger/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ import (
"github.com/pipe-cd/pipe/pkg/model"
)

func (t *Trigger) triggerDeployment(ctx context.Context, app *model.Application, branch string, commit git.Commit, commander string) (deployment *model.Deployment, err error) {
deployment, err = buildDeployment(app, branch, commit, commander, time.Now())
func (t *Trigger) triggerDeployment(
ctx context.Context,
app *model.Application,
branch string,
commit git.Commit,
commander string,
syncStrategy model.SyncStrategy,
) (deployment *model.Deployment, err error) {
deployment, err = buildDeployment(app, branch, commit, commander, syncStrategy, time.Now())
if err != nil {
return
}
Expand Down Expand Up @@ -97,7 +104,14 @@ func (t *Trigger) reportMostRecentlyTriggeredDeployment(ctx context.Context, d *
return err
}

func buildDeployment(app *model.Application, branch string, commit git.Commit, commander string, now time.Time) (*model.Deployment, error) {
func buildDeployment(
app *model.Application,
branch string,
commit git.Commit,
commander string,
syncStrategy model.SyncStrategy,
now time.Time,
) (*model.Deployment, error) {
commitURL := ""
if r := app.GitPath.Repo; r != nil {
var err error
Expand All @@ -124,8 +138,9 @@ func buildDeployment(app *model.Application, branch string, commit git.Commit, c
Url: commitURL,
CreatedAt: int64(commit.CreatedAt),
},
Commander: commander,
Timestamp: now.Unix(),
Commander: commander,
Timestamp: now.Unix(),
SyncStrategy: syncStrategy,
},
GitPath: app.GitPath,
CloudProvider: app.CloudProvider,
Expand Down
8 changes: 4 additions & 4 deletions pkg/app/piped/trigger/trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (t *Trigger) checkCommand(ctx context.Context) error {
)
continue
}
d, err := t.syncApplication(ctx, app, cmd.Commander)
d, err := t.syncApplication(ctx, app, cmd.Commander, syncCmd.SyncStrategy)
if err != nil {
t.logger.Error("failed to sync application",
zap.String("app-id", app.Id),
Expand All @@ -195,7 +195,7 @@ func (t *Trigger) checkCommand(ctx context.Context) error {
return nil
}

func (t *Trigger) syncApplication(ctx context.Context, app *model.Application, commander string) (*model.Deployment, error) {
func (t *Trigger) syncApplication(ctx context.Context, app *model.Application, commander string, syncStrategy model.SyncStrategy) (*model.Deployment, error) {
_, branch, headCommit, err := t.updateRepoToLatest(ctx, app.GitPath.Repo.Id)
if err != nil {
return nil, err
Expand All @@ -205,7 +205,7 @@ func (t *Trigger) syncApplication(ctx context.Context, app *model.Application, c
t.logger.Info(fmt.Sprintf("application %s will be synced because of a sync command", app.Id),
zap.String("head-commit", headCommit.Hash),
)
d, err := t.triggerDeployment(ctx, app, branch, headCommit, commander)
d, err := t.triggerDeployment(ctx, app, branch, headCommit, commander, syncStrategy)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -279,7 +279,7 @@ func (t *Trigger) checkApplication(ctx context.Context, app *model.Application,
logger.Info("application should be synced because of the new commit",
zap.String("most-recently-triggered-commit", preCommitHash),
)
if _, err := t.triggerDeployment(ctx, app, branch, headCommit, ""); err != nil {
if _, err := t.triggerDeployment(ctx, app, branch, headCommit, "", model.SyncStrategy_NONE); err != nil {
return err
}
t.mostRecentlyTriggeredCommits[app.Id] = headCommit.Hash
Expand Down
2 changes: 2 additions & 0 deletions pkg/app/web/src/__fixtures__/dummy-command.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SyncStrategy } from "pipe/pkg/app/web/model/deployment_pb";
import { Command, CommandModel, CommandStatus } from "../modules/commands";
import { dummyDeployment } from "./dummy-deployment";

Expand All @@ -14,6 +15,7 @@ export const dummyCommand: Command = {
type: CommandModel.Type.SYNC_APPLICATION,
syncApplication: {
applicationId: "app-1",
syncStrategy: SyncStrategy.NONE,
},
createdAt: 0,
updatedAt: 0,
Expand Down
2 changes: 2 additions & 0 deletions pkg/app/web/src/__fixtures__/dummy-deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { dummyApplication } from "./dummy-application";
import { dummyEnv } from "./dummy-environment";
import { dummyPiped } from "./dummy-piped";
import { dummyStage } from "./dummy-stage";
import { SyncStrategy } from "pipe/pkg/app/web/model/deployment_pb";

export const dummyDeployment: Deployment = {
id: "deployment-1",
Expand All @@ -27,6 +28,7 @@ export const dummyDeployment: Deployment = {
pullRequest: 123,
url: "",
},
syncStrategy: SyncStrategy.NONE,
},
updatedAt: 1,
version: "0.0.0",
Expand Down
2 changes: 2 additions & 0 deletions pkg/app/web/src/api/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ export const addApplication = async ({

export const syncApplication = async ({
applicationId,
syncStrategy,
}: SyncApplicationRequest.AsObject): Promise<
SyncApplicationResponse.AsObject
> => {
const req = new SyncApplicationRequest();
req.setApplicationId(applicationId);
req.setSyncStrategy(syncStrategy);
return apiRequest(req, apiClient.syncApplication);
};

Expand Down
2 changes: 2 additions & 0 deletions pkg/app/web/src/components/pipeline.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Pipeline } from "./pipeline";
import { Deployment, Stage } from "../modules/deployments";
import { dummyStage } from "../__fixtures__/dummy-stage";
import { METADATA_APPROVED_BY } from "../constants/metadata-keys";
import { SyncStrategy } from "pipe/pkg/app/web/model/deployment_pb";

const stage = (props?: Partial<Stage>): Stage => ({
...dummyStage,
Expand Down Expand Up @@ -44,6 +45,7 @@ const fakeDeployment: Deployment = {
},
commander: "cakecatz",
timestamp: 1592201366,
syncStrategy: SyncStrategy.NONE,
},
runningCommitHash: "3808585b46f1e90196d7ffe8dd04c807a251febc",
summary: "This deployment is debug",
Expand Down
4 changes: 3 additions & 1 deletion pkg/app/web/src/modules/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ApplicationGitRepository,
ApplicationKind,
} from "pipe/pkg/app/web/model/common_pb";
import { SyncStrategy } from "pipe/pkg/app/web/model/deployment_pb";
import { fetchCommand, CommandStatus, CommandModel } from "./commands";
import { AppState } from ".";

Expand Down Expand Up @@ -53,7 +54,8 @@ export const syncApplication = createAsyncThunk<
{ applicationId: string }
>("applications/sync", async ({ applicationId }, thunkAPI) => {
const { commandId } = await applicationsAPI.syncApplication({
applicationId,
applicationId: applicationId,
syncStrategy: SyncStrategy.NONE,
});

await thunkAPI.dispatch(fetchCommand(commandId));
Expand Down
1 change: 0 additions & 1 deletion pkg/config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ go_test(
deps = [
"//pkg/model:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
"@com_github_magiconair_properties//assert:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@com_github_stretchr_testify//require:go_default_library",
],
Expand Down
2 changes: 2 additions & 0 deletions pkg/model/command.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package pipe.model;
option go_package = "github.com/pipe-cd/pipe/pkg/model";

import "validate/validate.proto";
import "pkg/model/deployment.proto";

enum CommandStatus {
COMMAND_NOT_HANDLED_YET = 0;
Expand All @@ -36,6 +37,7 @@ message Command {

message SyncApplication {
string application_id = 1 [(validate.rules).string.min_len = 1];
model.SyncStrategy sync_strategy = 2;
}

message UpdateApplicationConfig {
Expand Down
7 changes: 7 additions & 0 deletions pkg/model/deployment.proto
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,18 @@ message Deployment {
int64 updated_at = 102 [(validate.rules).int64.gte = 0];
}

enum SyncStrategy {
NONE = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NONE is a bit confusable to me. I feel like it would be better to use AUTO or UNDEFINED or something like that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. AUTO looks good.

QUICK_SYNC = 1;
PIPELINE = 2;
}

message DeploymentTrigger {
Commit commit = 1 [(validate.rules).message.required = true];
// Who triggered this deployment via web page.
string commander= 2;
int64 timestamp = 3 [(validate.rules).int64.gt = 0];
SyncStrategy sync_strategy = 4;
}

message PipelineStage {
Expand Down