Skip to content
Open
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
7 changes: 6 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ inputs:
description: "Path to a local bash script (relative to app_path) executed inline over SSH on the instance before docker compose"
required: false
default: ""
templated_url:
description: "Template for the preview URL displayed in PR comments and outputs (use {{ pullpreview_url }} as placeholder, e.g. {{ pullpreview_url }}/custom/path?key=value)"
required: false
default: ""
ttl:
description: "Maximum time to live for deployments (e.g. 10h, 5d, infinite)"
required: false
Expand Down Expand Up @@ -168,7 +172,8 @@ runs:
--registries "${{ inputs.registries }}" \
--proxy-tls "${{ inputs.proxy_tls }}" \
--pre-script "${{ inputs.pre_script }}" \
--ttl "${{ inputs.ttl }}"
--ttl "${{ inputs.ttl }}" \
--templated-url "${{ inputs.templated_url }}"

if grep -q '^url=' "${GITHUB_OUTPUT}"; then
echo "live=true" >> "${GITHUB_OUTPUT}"
Expand Down
2 changes: 2 additions & 0 deletions cmd/pullpreview/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func runGithubSync(ctx context.Context, args []string, logger *pullpreview.Logge
label := fs.String("label", "pullpreview", "Label to use for triggering preview deployments")
deploymentVariant := fs.String("deployment-variant", "", "Deployment variant (4 chars max)")
ttl := fs.String("ttl", "infinite", "Maximum time to live for deployments (e.g. 10h, 5d, infinite)")
templatedURL := fs.String("templated-url", "", "Template for the preview URL (use {{ pullpreview_url }} as placeholder)")
commonFlags := registerCommonFlags(fs)
leadingPath, parseArgs := splitLeadingPositional(args)
fs.Parse(parseArgs)
Expand All @@ -137,6 +138,7 @@ func runGithubSync(ctx context.Context, args []string, logger *pullpreview.Logge
Label: *label,
DeploymentVariant: *deploymentVariant,
TTL: *ttl,
TemplatedURL: *templatedURL,
Context: ctx,
Common: commonOptions,
}
Expand Down
30 changes: 28 additions & 2 deletions internal/pullpreview/github_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,10 @@ func (g *GithubSync) Sync() error {
return err
}
if upInstance != nil {
_ = g.updateGitHubStatus(statusDeployed, upInstance.URL())
g.writeStepSummary(statusDeployed, action, upInstance.URL(), upInstance)
displayURL := g.applyTemplatedURL(upInstance.URL())
_ = g.updateGitHubStatus(statusDeployed, displayURL)
g.writeStepSummary(statusDeployed, action, displayURL, upInstance)
g.writeTemplatedURLOutput(displayURL)
}
}
return nil
Expand Down Expand Up @@ -722,6 +724,30 @@ func (g *GithubSync) writeStepSummary(status deploymentStatus, action actionType
}
}

func (g *GithubSync) applyTemplatedURL(rawURL string) string {
tpl := strings.TrimSpace(g.opts.TemplatedURL)
if tpl == "" {
return rawURL
}
return strings.ReplaceAll(tpl, "{{ pullpreview_url }}", rawURL)
}

func (g *GithubSync) writeTemplatedURLOutput(displayURL string) {
if strings.TrimSpace(g.opts.TemplatedURL) == "" {
return
}
path := os.Getenv("GITHUB_OUTPUT")
if path == "" {
return
}
f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return
}
defer f.Close()
fmt.Fprintf(f, "url=%s\n", displayURL)
}

func (g *GithubSync) workflowRunURL() string {
server := strings.TrimSuffix(os.Getenv("GITHUB_SERVER_URL"), "/")
runID := strings.TrimSpace(os.Getenv("GITHUB_RUN_ID"))
Expand Down
63 changes: 63 additions & 0 deletions internal/pullpreview/github_sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,69 @@ func TestRenderStepSummaryForDeployedState(t *testing.T) {
}
}

func TestApplyTemplatedURL(t *testing.T) {
event := loadFixtureEvent(t, "github_event_labeled.json")
tests := []struct {
name string
templatedURL string
rawURL string
want string
}{
{
name: "empty template returns raw URL",
templatedURL: "",
rawURL: "http://pr-1-ip-1-2-3-4.my.preview.run:80",
want: "http://pr-1-ip-1-2-3-4.my.preview.run:80",
},
{
name: "template with custom path",
templatedURL: "{{ pullpreview_url }}/custom/path?key=value",
rawURL: "http://pr-1-ip-1-2-3-4.my.preview.run:80",
want: "http://pr-1-ip-1-2-3-4.my.preview.run:80/custom/path?key=value",
},
{
name: "template with encoded params",
templatedURL: "{{ pullpreview_url }}/abc?redirectTo=def%2Fghi",
rawURL: "https://pr-1-ip-1-2-3-4.my.preview.run:443",
want: "https://pr-1-ip-1-2-3-4.my.preview.run:443/abc?redirectTo=def%2Fghi",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sync := newSync(event, GithubSyncOptions{Label: "pullpreview", TemplatedURL: tt.templatedURL, Common: CommonOptions{}}, &fakeGitHub{}, fakeProvider{running: true})
got := sync.applyTemplatedURL(tt.rawURL)
if got != tt.want {
t.Fatalf("applyTemplatedURL()=%q, want %q", got, tt.want)
}
})
}
}

func TestSyncLabeledWithTemplatedURLUsesTemplateInComment(t *testing.T) {
t.Setenv("PULLPREVIEW_TEST", "1")
t.Setenv("GITHUB_SERVER_URL", "https://github.com")
t.Setenv("GITHUB_RUN_ID", "12345")
t.Setenv("GITHUB_STEP_SUMMARY", filepath.Join(t.TempDir(), "summary.md"))
event := loadFixtureEvent(t, "github_event_labeled.json")
client := &fakeGitHub{latestSHA: event.PullRequest.Head.SHA}
sync := newSync(event, GithubSyncOptions{
Label: "pullpreview",
TemplatedURL: "{{ pullpreview_url }}/app?lang=en",
Common: CommonOptions{},
}, client, fakeProvider{running: true})

if err := sync.Sync(); err != nil {
t.Fatalf("Sync() returned error: %v", err)
}
if len(client.updatedComments) == 0 {
t.Fatalf("expected PR comment update on deployed state")
}
lastComment := client.updatedComments[len(client.updatedComments)-1]
if !strings.Contains(lastComment, "/app?lang=en") {
t.Fatalf("expected templated URL with custom path in PR comment, got %q", lastComment)
}
}

func TestRunGithubSyncFromEnvironmentRunsDownForBranchPush(t *testing.T) {
t.Setenv("PULLPREVIEW_TEST", "1")
event := loadFixtureEvent(t, "github_event_push_solo_organization.json")
Expand Down
1 change: 1 addition & 0 deletions internal/pullpreview/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ type GithubSyncOptions struct {
Label string
DeploymentVariant string
TTL string
TemplatedURL string
Context context.Context
Common CommonOptions
}
Loading