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
16 changes: 13 additions & 3 deletions internal/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func newRunCmd() *cobra.Command {
var targetRepo string
var fullsendBinary string
var envFiles []string
var noPostScript bool

cmd := &cobra.Command{
Use: "run <agent-name>",
Expand All @@ -34,7 +35,7 @@ func newRunCmd() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
agentName := args[0]
printer := ui.New(os.Stdout)
return runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary, envFiles, printer)
return runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary, envFiles, noPostScript, printer)
},
}

Expand All @@ -43,13 +44,14 @@ func newRunCmd() *cobra.Command {
cmd.Flags().StringVar(&targetRepo, "target-repo", "", "path to the target repository")
cmd.Flags().StringVar(&fullsendBinary, "fullsend-binary", "", "path to a Linux fullsend binary to copy into the sandbox (default: current executable)")
cmd.Flags().StringArrayVar(&envFiles, "env-file", nil, "load environment variables from a dotenv file (repeatable)")
cmd.Flags().BoolVar(&noPostScript, "no-post-script", false, "skip post-script execution (agent still runs full inference)")
_ = cmd.MarkFlagRequired("fullsend-dir")
_ = cmd.MarkFlagRequired("target-repo")

return cmd
}

func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary string, envFiles []string, printer *ui.Printer) (runErr error) {
func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary string, envFiles []string, noPostScript bool, printer *ui.Printer) (runErr error) {
printer.Banner()
printer.Blank()
printer.Header("Running agent: " + agentName)
Expand Down Expand Up @@ -143,7 +145,11 @@ func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary str
printer.KeyValue("Pre-script", h.PreScript)
}
if h.PostScript != "" {
printer.KeyValue("Post-script", h.PostScript)
if noPostScript {
printer.KeyValue("Post-script", h.PostScript+" (SKIPPED: --no-post-script)")
} else {
printer.KeyValue("Post-script", h.PostScript)
}
}
if h.TimeoutMinutes > 0 {
printer.KeyValue("Timeout", fmt.Sprintf("%d minutes", h.TimeoutMinutes))
Expand Down Expand Up @@ -230,6 +236,10 @@ func runAgent(agentName, fullsendDir, outputBase, targetRepo, fullsendBinary str
// any output checks it needs.
if h.PostScript != "" {
defer func() {
if noPostScript {
printer.StepWarn(fmt.Sprintf("Skipping post-script %s: --no-post-script", h.PostScript))
return
}
if h.ValidationLoop != nil && !validationPassed {
printer.StepWarn("Skipping post-script: validation did not pass")
return
Expand Down
7 changes: 7 additions & 0 deletions internal/cli/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ func TestRunCommand_RegisteredOnRoot(t *testing.T) {
assert.True(t, found, "run command should be registered on root")
}

func TestRunCommand_HasNoPostScriptFlag(t *testing.T) {
cmd := newRunCmd()
flag := cmd.Flags().Lookup("no-post-script")
require.NotNil(t, flag)
assert.Equal(t, "false", flag.DefValue)
}

func TestRunCommand_HasOutputDirFlag(t *testing.T) {
cmd := newRunCmd()
flag := cmd.Flags().Lookup("output-dir")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ runs:
run: |
set -euo pipefail
mkdir -p "${GITHUB_WORKSPACE}/output"
# SECURITY: Never expose --no-post-script as a workflow input.
# Post-scripts enforce secret scanning, protected-path blocks,
# and review-downgrade controls. Skipping them in CI bypasses
# all post-push security gates.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[important — deferred] Good defensive comment. Worth noting: this is documentation of intent, not enforcement. A workflow that calls fullsend run directly (bypassing the composite action) could pass --no-post-script in CI.

A future hardening pass could add a programmatic guard — e.g., detect GITHUB_ACTIONS=true and refuse or warn when --no-post-script is used in CI. CODEOWNERS protection on .github/ provides a secondary control for now.

Not blocking this PR — flagging for future consideration.

fullsend run "${AGENT}" \
--fullsend-dir "${GITHUB_WORKSPACE}" \
--output-dir "${GITHUB_WORKSPACE}/output" \
Expand Down
Loading