akuity / kargo

Application lifecycle orchestration
https://kargo.akuity.io/
Apache License 2.0
1.52k stars 132 forks source link

branch on git subs can be implicitly HEAD when not specified #762

Open jessesuen opened 12 months ago

jessesuen commented 12 months ago

Tripped on this trying to onboard a new kargo project

.writeBranch: Invalid value: "": spec.promotionMechanisms.gitRepoUpdates[0].writeBranch in body should be at least 1 chars long

writeBranch can be implicitly HEAD of the remote, if user doesn't supply it. This would cut down on our boilerplate and make examples more universally compatible.

krancour commented 12 months ago

We need to be careful with this one. I think the read branch is implicitly HEAD if not specified. If read and write branch are the same, a loop can be created. I think. It's been a while since I looked at this. I'll dig into it some tomorrow.

krancour commented 12 months ago

It also should be out of the ordinary to write to the head of the repo's default branch. If branches aren't Stage-specific and promotions at all Stages are writing to the same branch, things get crazy quickly. Suppose "test" writes to main and then "uat" does the same. Now if the test App points at main, it's no longer pointing at the commit specified by the test Stage's current Freight -- which makes the test Stage appear unhealthy.

krancour commented 12 months ago

From godocs:

        // ReadBranch specifies a particular branch of the repository from which to
    // locate contents that will be written to the branch specified by the
    // WriteBranch field. This field is optional. In cases where a
    // StageStage includes a GitCommit, that commit's ID will supersede the
    // value of this field. Therefore, in practice, this field is only used to
    // clarify what branch of a repository can be treated as a source of manifests
    // or other configuration when a Stage has no subscription to that
    // repository.
    //
    //+kubebuilder:validation:Optional
    //+kubebuilder:validation:Pattern=`^(\w+([-/]\w+)*)?$`
    ReadBranch string `json:"readBranch"`

    // WriteBranch specifies the particular branch of the repository to be
    // updated. This is a required field.
    //
    //+kubebuilder:validation:MinLength=1
    //+kubebuilder:validation:Pattern=`^\w+([-/]\w+)*$`
    WriteBranch string `json:"writeBranch"`

Tangentially related:

    // GitSubscription defines a subscription to a Git repository.
    type GitSubscription struct {
    // URL is the repository's URL. This is a required field.
    //
    //+kubebuilder:validation:MinLength=1
    //+kubebuilder:validation:Pattern=`^((https?://)|([\w-]+@))([\w\d\.]+)(:[\d]+)?/(.*)$`
    RepoURL string `json:"repoURL"`
    // Branch references a particular branch of the repository. This is a required
    // field.
    //
    //+kubebuilder:validation:MinLength=1
    //+kubebuilder:validation:Pattern=`^\w+([-/]\w+)*$`
    Branch string `json:"branch"`
    }

Here Branch can quite easily stand to be optional because it would be completely unsurprising to subscribe to the default branch when no other branch is specified. I will make that so.

krancour commented 3 weeks ago

We can revisit this when time permits and if it is still relevant after work on #2219 is complete.

fwiw, the built-in prevention of "loop formation" (i.e. stopping you from writing to a branch you also subscribe to) was removed some time ago since the advent of include/exclude filters on git subscriptions has since made it possible, with the right configuration, to write to a branch you also subscribe to without forming a loop.