Skip to content

fix(cli): keep the Functions suffix for self-hosted function rules - #1918

Merged
HarshMN2345 merged 1 commit into
mainfrom
fix/cli-function-rule-domain-self-hosted
Sep 18, 2026
Merged

HarshMN2345 merged 1 commit into
mainfrom
fix/cli-function-rule-domain-self-hosted

Conversation

@HarshMN2345

Copy link
Copy Markdown
Member

Fixes appwrite/appwrite#13743. Replaces appwrite/sdk-for-cli#365, which patched the generated output instead of the template.

What happens

On a self-hosted install, appwrite push functions gives a newly created function a default proxy rule under the Sites domain:

expected  <unique>.functions.example.com
actual    <unique>.sites.example.com

Why

ruleDomains prepends _APP_DOMAIN_SITES to the Functions candidate list for every endpoint, and ensureDefaultRule takes domains[0] whenever the config carries no previewDomainLabel:

configured := variables.GetString("_APP_DOMAIN_" + strings.ToUpper(resource.Label))
if resource.Name == "function" {
    configured = variables.GetString("_APP_DOMAIN_SITES") + "," + configured
}
...
suffix := domains[0]

On Cloud that is harmless — the Sites suffix there is appwrite.network, which is also the Functions edge suffix, and leading with it is what lets functionDomainForTarget pick edge vs. region. Self-hosted, the two products have unrelated domains, so the Sites suffix simply wins.

Nothing downstream corrects it:

  • functionDomainForTarget only runs when a label is present (label != "" && resource.Name == "function"), and pull functions records previewDomainLabel only for .appwrite.network / .appwrite.run domains — so on self-hosted the label is always empty.
  • regionalRuleDomain and cloudFunctionDomains are both no-ops off Cloud.
  • The server does not reject it: validateDomainRestrictions permits one label under either product suffix, and the router resolves by hostname and re-derives the product from the deployment, so the mismatch never surfaces.

The issue's repro needs its delete step because ensureDefaultRule short-circuits on label == "" && len(items) > 0 — deleting the function cascades its rules away, so the re-push falls through to rule creation.

Introduced in CLI 27.2.0, which replaced body.Set("domain", appwrite.Unique()+"."+domains[0]) with the label/target logic and added the prepend.

The change

Gate the prepend on a Cloud endpoint. Cloud ordering is unchanged; a self-hosted install resolves its own Functions suffix.

Tests

TestSelfHostedPushRulesOnTheFunctionsDomain drives runPushDeployable against an httptest server and asserts the domain that arrives at POST /proxy/rules/function — so it covers ensureDefaultRule's domains[0] pick, not just ruleDomains. Against the unfixed template it reproduces the reported symptom:

initfunction_test.go:456: rule domain = "6aad1693002ee6c66418.sites.example.com"
--- FAIL: TestSelfHostedPushRulesOnTheFunctionsDomain

TestRuleDomainsKeepsEdgeGlobalAndRegionalisesCompute passes unmodified, which pins that Cloud ordering is untouched.

Regenerated per the pre-submit checklist:

php example.php cli
cd examples/cli && go build ./... && go vet ./... && go test ./...

gofmt -l examples/cli clean, composer lint-twig and composer refactor:check pass.

ruleDomains prepended _APP_DOMAIN_SITES to the Functions candidate list
for every endpoint, and ensureDefaultRule takes domains[0] whenever the
config carries no previewDomainLabel. On Cloud that is harmless, since
the Sites suffix there is appwrite.network, which is also the Functions
edge suffix. Self-hosted, the two products have unrelated domains, so
`appwrite push functions` minted the function's default rule under the
Sites suffix.

The Cloud selector that would have sorted this out never runs on a
self-hosted push: functionDomainForTarget is only reached when a label is
present, and `pull functions` records previewDomainLabel only for
.appwrite.network and .appwrite.run domains.

Gate the prepend on a Cloud endpoint so Cloud ordering is unchanged and a
self-hosted install resolves its own Functions suffix.

The new test drives runPushDeployable against an httptest server and
asserts the domain that arrives at POST /proxy/rules/function, so it
covers the domains[0] pick rather than restating ruleDomains' own input.
@greptile-apps

greptile-apps Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge and directly corrects the self-hosted domain-selection regression without changing recognized Cloud behavior.

Summary

This PR prevents self-hosted function pushes from using the Sites domain when creating a default proxy rule while retaining the existing Cloud domain ordering.

  • Gates the Sites-domain prepend on recognized Appwrite Cloud endpoints.
  • Adds an end-to-end command test that observes the domain posted to the proxy-rules API.
  • Leaves Cloud edge and regional Functions selection unchanged.

Reviews (1) · Last reviewed commit: "fix(cli): keep the Functions suffix for ..."

@HarshMN2345
HarshMN2345 merged commit 7a1c02d into main Sep 18, 2026
59 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Exsiting functions deployed from CLI use .site urls instead of .function

2 participants