feat: Remote builds from a git repository no longer require a local checkout - #4039
feat: Remote builds from a git repository no longer require a local checkout#4039gauron99 wants to merge 6 commits into
Conversation
Magic DNS patched the coredns deployment, slept, then waited for every kube-system pod to be Ready. The old coredns pods are terminating after the patch and never become Ready again, so the wait timed out after 60s on hosts where they took a while to go, and the whole cluster was torn down at the very last step. Wait for the deployment rollout instead: the new pods are available and the old ones are gone. hack/cluster.sh has the same sleep-and-wait, from which this was ported.
NewFunctionFromGit reads func.yaml from a revision of a remote repository (default branch, branch, tag or commit hash) in memory, and GitRemoteCommit reports the commit that revision resolves to. Both reuse 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. Groundwork for knative#3203.
The Tekton provider read two things from the local checkout that do not describe a build from a git repository: the commit label came from the local HEAD (fn.GitCommit on f.Root) rather than the revision the cluster clones, and a .tekton/ override was looked up under f.Root, which for a function without a Root resolved to the current directory. The commit is now resolved from the source the pipeline builds, via GitRemoteCommit for a git source, and before any cluster resource is created, so an unknown revision fails early. The override lookup is skipped without a Root, and uploading sources without a Root is refused with a clear error.
A remote deployment of a git repository had two sources of truth: the CLI built the Tekton pipeline from the local func.yaml while the cluster cloned the repository and read its func.yaml. The local copy existed only to feed the CLI, so it was required, and had to be on the right branch and in the right directory to match what the cluster built. The repository is now the source of the function when --remote has a git URL. The CLI reads func.yaml from the requested revision and directory (NewFunctionFromGit), applies the flags to that, and runs the pipeline for it. A local function at the path is optional. When present it records the request and the outcome (git settings, registry, deployed image, namespace, deployer, exposure) so describe, delete and later deploys find them, and its own metadata is left untouched. The prompts of build, run and deploy take the loaded function instead of loading one from the path themselves, and Validate no longer demands a Root: where a function lives is not part of its correctness, and Write is what needs one. The branch-mismatch warning is gone with the mismatch. Closes knative#3203.
|
Skipping CI for Draft Pull Request. |
|
[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 DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
🟡 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.yamldirectly 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.
| // For now, give a more helpful error. | ||
| return errors.New("please ensure the function's source is also available locally") | ||
| } | ||
| if f, err = cfg.function(cmd.Context(), local); err != nil { |
| // A local function at path, if there is one, records the request and the | ||
| // outcome so that later commands (describe, delete, another deploy) find | ||
| // them; its own metadata is left alone. |
| // checkout otherwise. | ||
| func sourceCommit(ctx context.Context, f fn.Function) (string, error) { | ||
| if f.Build.Git.URL != "" { | ||
| commit, err := fn.GitRemoteCommit(ctx, f.Build.Git) |
| return wrapValidateError(err, "deploy") | ||
| } | ||
| // The prompt may have made the source a git repository | ||
| if cfg.Remote && cfg.GitURL != "" && f.Root != "" { |
| local.Deploy.Namespace = f.Deploy.Namespace | ||
| local.Deploy.Deployer = f.Deploy.Deployer | ||
| local.Deploy.Expose = f.Deploy.Expose | ||
| f = local |
TestRemote_Source, TestRemote_Ref and TestRemote_Dir cloned the repository, checked out the branch or changed into the subdirectory before deploying, because the CLI read the function's metadata from the local func.yaml. The function now comes from the repository, so the tests deploy from an empty directory, which is what they set out to cover.
7bf2697 to
a2d8a9a
Compare
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.
a2d8a9a to
4ebfbf9
Compare
Changes
func deploy --remote --git-url 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 branch and directory being built.
Prerequisite: #4038 (wait for the CoreDNS rollout in func cluster create). This branch includes that commit; it was needed to get a local cluster up for the verification below.
Pre-existing and out of scope: deploy-intent flags (--deployer, --expose, --env) do not reach the cluster in the git path, and private repositories are still fetched anonymously on the cluster.
testing
Verified on a kind cluster with Tekton: the four remote e2e tests pass, plus manual deploys from an empty directory by branch and by subdirectory, from a checkout on another branch, a wrong revision (no PipelineRun created) and a redeploy on the same volume.
/kind enhancement
Fixes #3203
Release Note
release-note
func deploy --remote --git-urlno longer needs a local copy of the function:func.yamlis read from the repository at the requested--git-branchand--git-dir. Deploying the same function from git a second time no longer fails in the clone step.