Skip to content

feat: Remote git builds need no local checkout and build the commit they read - #4039

Closed
gauron99 wants to merge 7 commits into
knative:mainfrom
gauron99:push-mmxznyrpmwxy
Closed

gauron99 wants to merge 7 commits into
knative:mainfrom
gauron99:push-mmxznyrpmwxy

Conversation

@gauron99

@gauron99 gauron99 commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Changes

func deploy --remote --source built the pipeline from the local func.yaml while the cluster cloned the repository and read its own. The local copy existed only to feed the CLI, so it was required and had to match the revision and directory being built.

  • 🎁 The repository is now the source of the function: NewFunctionFromGit reads func.yaml from the requested revision (the remote's default branch, a branch, a tag or a commit) and --source-dir, in memory and with no checkout, and the flags apply to that. A local function at the path is optional; when present it only records the source settings and the outcome (image, namespace, deployer, exposure). An unknown revision fails in the CLI before any cluster resource is created. Migrations take the serialized bytes instead of re-reading f.Root, so a function without a working tree can be migrated.
  • 🐛 The cluster now builds and labels exactly the commit that was read. The commit the revision resolved to travels in memory only (Build.Source.Commit, never written to func.yaml), the PipelineRun fetches that hash, and the image carries it in org.opencontainers.image.revision. Before, the cluster cloned by name, so a branch could move between the read and the build, and the label was the local checkout's HEAD: the wrong commit for a git source, and missing without one. Uploaded sources are unchanged and keep the local working tree's HEAD.
  • 🐛 An empty revision is no longer turned into a hard-coded main. It reaches the git-clone step as configured, and git then fetches the remote's default branch, whatever it is called. The revision is also quoted in both PipelineRun templates, so a tag such as 1.10 is no longer read as the number 1.1.
  • 🐛 A second remote build of the same function from git failed in the fetch step: the git-clone StepAction (user 65532) could not clear sources left by the build user (1001). A root clean-src step empties the workspace before the clone; the upload path and the cache workspace are untouched.
  • 🧹 The remote git e2e tests deploy from an empty directory, dropping their clone/checkout/cd workarounds.

Pre-existing and out of scope: deploy intent given on the command line (--env, --deployer, --expose, --service-account) does not reach the cluster in the git path. The PipelineRun carries build inputs only, and the deploy step reads the repository's committed func.yaml; on the upload path the same flags do travel, inside the func.yaml the CLI writes into the volume. --namespace is the exception: the PipelineRun runs in the namespace the CLI resolved and an unset namespace in the repository resolves to it, though a namespace committed in func.yaml still wins. Private repositories are also still fetched anonymously on the cluster, and the OpenShift vcs-ref annotation still comes from build.source.revision rather than the built commit.

testing

Verified on a kind cluster with Tekton, against a git server holding a repository whose default branch is trunk with no main at all, tags 1.0 and 1.10, and a branch feature, each ref answering with its own body:

  • with no --revision, trunk is built; before this branch the same deploy fails with couldn't find remote ref main
  • --revision 1.10 builds that tag; before this branch the value reaches Tekton as the number 1.1
  • a tag, a branch and a pinned commit each build the right commit, with both the pack and the s2i builder
  • the image's org.opencontainers.image.revision is the built commit, and pushing to the branch between the read and the fetch no longer changes what is built
  • deploying from an empty directory works, and a second git deploy on the same volume succeeds, which fails without the clean-src step

The existing TestRemote_* e2e suite has not been rerun on this branch.

/kind enhancement

Relates to #3203

Release Note

`func deploy --remote --source` no longer needs a local copy of the function: `func.yaml` is read from the repository at the given `--revision` and `--source-dir`, and the cluster builds and labels the image with exactly the commit that was read. An empty revision uses the remote's default branch instead of a hard-coded "main", a tag such as `1.10` is no longer misread as a number, and deploying the same function from git a second time no longer fails in the clone step.

Docs


@knative-prow

knative-prow Bot commented Sep 2, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@knative-prow knative-prow Bot added do-not-merge/work-in-progress 🤖 PR should not merge because it is a work in progress. kind/enhancement Feature additions or improvements to existing labels Sep 2, 2026
@gauron99
gauron99 requested a balanced review from Copilot and removed request for dsimansk and jrangelramos September 2, 2026 22:46
@knative-prow

knative-prow Bot commented Sep 2, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: gauron99

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow Bot added approved 🤖 PR has been approved by an approver from all required OWNERS files. size/XXL 🤖 PR changes 1000+ lines, ignoring generated files. labels Sep 2, 2026

Copilot AI left a comment

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.

🟡 Changes recommended

Remote metadata, built source, and persisted deployment identity can diverge in several supported flows.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Enables remote git deployments without a local function checkout and includes the CoreDNS rollout prerequisite.

Changes:

  • Loads and migrates func.yaml directly from git.
  • Resolves source commits and cleans Tekton workspaces before cloning.
  • Updates CLI flows, tests, E2E coverage, and documentation.
File summaries
File Description
pkg/pipelines/tekton/templates.go Supports rootless functions and commit labels.
pkg/pipelines/tekton/templates_test.go Tests rootless pipeline rendering.
pkg/pipelines/tekton/tasks_test.go Verifies cleanup-step ordering.
pkg/pipelines/tekton/task-s2i.yaml.tmpl Cleans git source workspace.
pkg/pipelines/tekton/task-buildpack.yaml.tmpl Cleans git source workspace.
pkg/pipelines/tekton/source_commit_test.go Tests source commit resolution.
pkg/pipelines/tekton/pipelines_provider.go Resolves commits before resource creation.
pkg/functions/git_commit.go Adds remote commit lookup.
pkg/functions/function.go Parses rootless serialized functions.
pkg/functions/function_migrations.go Migrates directly from serialized bytes.
pkg/functions/function_git.go Loads functions from git revisions.
pkg/functions/function_git_test.go Tests git loading and migration.
pkg/functions/client.go Reuses serialized-function parsing.
pkg/cluster/dns.go Waits for the CoreDNS rollout.
e2e/e2e_remote_test.go Removes local checkout workarounds.
docs/reference/func_deploy.md Documents checkout-free deployment.
cmd/run.go Supplies function context to prompts.
cmd/deploy.go Selects and persists remote functions.
cmd/deploy_test.go Tests checkout-free deploy behavior.
cmd/config_git_set.go Supplies function context to prompts.
cmd/build.go Supplies function context to prompts.
Review details
  • Files reviewed: 21/22 changed files
  • Comments generated: 5
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmd/deploy.go Outdated
Comment thread cmd/deploy.go Outdated
Comment thread pkg/pipelines/tekton/pipelines_provider.go Outdated
Comment thread cmd/deploy.go Outdated
Comment thread cmd/deploy.go Outdated
@gauron99
gauron99 force-pushed the push-mmxznyrpmwxy branch 2 times, most recently from a2d8a9a to 4ebfbf9 Compare September 3, 2026 05:02
@knative-prow-robot knative-prow-robot added the needs-rebase Cannot be merged due to conflicts with HEAD. label Sep 14, 2026
@knative-prow-robot knative-prow-robot removed the needs-rebase Cannot be merged due to conflicts with HEAD. label Sep 22, 2026
@gauron99
gauron99 requested a balanced review from Copilot September 22, 2026 19:34
@gauron99 gauron99 changed the title feat: Remote builds from a git repository no longer require a local checkout feat: Remote git builds need no local checkout and build the commit they read Sep 22, 2026

Copilot AI left a comment

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.

Comment thread cmd/deploy.go Outdated
Comment thread pkg/functions/function_git.go Outdated
Comment thread cmd/deploy.go Outdated

Copilot AI left a comment

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.

Copilot review overview

🟡 Changes recommended

Interactive choices can be overwritten, and rootless source revision handling can panic or apply an unrelated local commit label.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 High severity · 2 Medium severity · 1 Low severity

Open (5)
Resolved since last review (2)

Comment thread pkg/pipelines/tekton/templates.go Outdated
Comment thread cmd/deploy.go Outdated
Comment thread pkg/pipelines/tekton/templates.go Outdated
Comment thread cmd/deploy.go Outdated
…d at

The image's revision label came from the local checkout's HEAD for
every remote build. For a function read from its repository that is
the wrong commit, or none. Source gains an in-memory Commit, the hash the
revision resolved to when the function was read; when set, the
PipelineRun fetches that commit and labels the image with it, so what
was read is what is built. Uploaded sources keep the local HEAD.

The PipelineRun no longer turns an empty revision into a hard-coded
"main": the revision goes to the fetch step as configured, and an empty
one fetches the remote's default branch, whatever its name.
NewFunctionFromGit reads func.yaml from a revision of a remote repository
(default branch, branch, tag or commit hash) in memory, and records the
commit that revision resolved to in Build.Source.Commit, for the build to
fetch and label. It reuses the credential lookup the template repositories
already use.

Migrations used to re-read the on-disk func.yaml from f.Root to see the
previous structure, so a function with no working tree could not be
migrated. hasInitializedFunction in the client hit the same problem by
migrating an unmarshalled function that had no Root. Migrations now
receive the serialized bytes they were parsed from, and NewFunction,
NewFunctionFromGit and hasInitializedFunction share parseFunction.

The build prompt takes the function instead of reading it from a path,
so it works for a function that is not on disk. It no longer asks for
the project path: every other default it offers already came from the
function at the original path, and a changed answer was reloaded by
build and run but silently ignored by deploy and config git set. The
path is given with --path, as before, and each command reads the
function once.

Groundwork for knative#3203.
The git-clone StepAction runs as user 65532 and empties the source
workspace before cloning. The previous run of the pipeline leaves the
sources there owned by the build user (the prepare step chowns the tree
to 1001 for the buildpacks lifecycle), which 65532 can neither delete
nor create .git next to. Every remote build of a function from git after
its first therefore failed in the fetch step, until func delete removed
the volume.

A clean-src step, run as root and gated on a git URL like fetch-src,
now empties the workspace and hands the directory to the clone user
before the clone. The upload path is unaffected, and the cache
workspace is a separate directory that is left alone.
The flag defaults of deploy are derived from the function in the current
directory when the command is built, so a local func.yaml is honoured
unless a flag or environment variable overrides it. A function read from
a git repository is known only at run time and got no such treatment:
from an empty directory the static defaults applied, and Configure then
overwrote, for example, the repository's s2i builder with pack.

withFunctionDefaults gives the config the defaults NewDeployCmd would
have registered had the repository's function been the local one, for
every flag the user did not set. The reload after the prompt now also
happens when the prompt changed the git source of a function that
already came from git, not only when it made a local function remote.
A remote deployment of a git repository recorded the git settings and
the outcome (image, namespace, deployer, exposure) on whatever local
function was at the path, a habit from when the local func.yaml was the
source of such a deployment. It was wrong for a checkout on another
branch, misleading for a different function, and it stamped sources
that were never built.

Such a deployment is now a deployment by reference: the function is
read from the repository, deployed, and nothing is written, neither to
the repository nor to the current directory. To change a function that
lives in a repository, clone it, edit it and deploy the working tree.
A func.yaml may still carry build.source settings, which serve as the
defaults of the --source flags. Loading is one function, loadFunction,
without a local function to consult.
@knative-prow-robot knative-prow-robot added the needs-rebase Cannot be merged due to conflicts with HEAD. label Sep 30, 2026
@knative-prow-robot

Copy link
Copy Markdown

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@gauron99

gauron99 commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

this PR is broken down into smaller items of which first one is #4064, closing that in favor of 4064

@gauron99 gauron99 closed this Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved 🤖 PR has been approved by an approver from all required OWNERS files. do-not-merge/work-in-progress 🤖 PR should not merge because it is a work in progress. kind/enhancement Feature additions or improvements to existing needs-rebase Cannot be merged due to conflicts with HEAD. size/XXL 🤖 PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants