Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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_AUTO,
},
}
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_AUTO); 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.AUTO,
},
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.AUTO,
},
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.AUTO,
},
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.AUTO,
});

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 {
AUTO = 0;
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