Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semantic versioning proposal #842

Open
et1975 opened this issue Dec 8, 2021 · 5 comments
Open

Semantic versioning proposal #842

et1975 opened this issue Dec 8, 2021 · 5 comments

Comments

@et1975
Copy link
Contributor

et1975 commented Dec 8, 2021

I often find the API has been broken within the same major version.
Would it make sense to start using semantic versioning to give the user indication - "broken API ahead"?

@isaacabraham
Copy link
Member

@et1975 Yes, we should probably do something like that. Up until now we've been fairly lax on versioning with regards to the API except for two things:

  1. Breaks should be immediately obvious i.e. compile-time, and simple to fix.
  2. We're quite strict around the emitting of the ARM itself - we don't want to change that unless fixing a bug.

@stroborobo
Copy link

Hey I've thinking about this, maybe it's too much, since it touches on a lot of stuff.

The ARM templates follow a spec that is versioned, this is currently not represented in the API or package version. Updating the resource type version to support new features seems like a hard decision to make, since it might have unintended consequences, as Farmer is technically targeting a different Azure API, which might behave differently regardless of changes in the JSON. The strictness in changing the ARM output might not be very helpful, since it sets incentives to keep outdated implementations, that might not even work anymore.

What if the builders were versioned according to the spec? Like instead of containerApp { ... } it'd be containerApp.v20221001 { ... } and containerApp.latest { ... }. Updates to the output would be explicit and breaking changes would not be blocked by forced compatibility to previous versions, both in the ARM output as well as in the builder's API.

While this isn't really about semantic versioning, it could help to reduce breakages.

I'm not sure how to structure the builders internally for this, this could either mean a bunch of duplication in the code base or some major changes internally.

I've been toying with the idea of computation expression builders (like builder builders?) to keep the API (mostly?) stable and reduce duplication while enabling these versioned builders. Idk if a lib like it already exists to enable this, but it would be nice if you could be more explicit about the resource version you're targeting. Exactly because things might not work as expected sometimes and you'd need to target a specific one sometimes.

The idea is kind of inspired by how applicative form builders work, not exactly like Fable.Form, but somewhat like it. So you'd reuse/reference field definitions from previous versions and compose them together into a CE, that looks like the one we have today.

I'm not sure if it's possible to build usable CEs at runtime though, so this approach might be a flop. Versioned builders would be neat though imo.

@ninjarobot
Copy link
Collaborator

I may have misinterpreted the OP, but I believe this issue is about breakage in Farmer rather than API changes in ARM. It's frustrating to when code breaks just because of a package update.

Usually the builders can be made backwards compatible. This is probably one of my biggest revisions I request when reviewing. Breakage more often comes from complex parameter types that don't use a builder, which means that adding a field to a record will break anyone using it.

We really can't guarantee any backwards compatibility on the resource records that the builders are creating. This should be considered a public but not stable API.

For the ARM API versions, those can nearly always increment without any issue, so long as there is no structural change. It is up to the the resource providers to ensure this, but the ARM team also heavily gates breaking changes. A new ARM API version in and of itself does not change anything at all on the underlying resource. It may expose more options, but the underlying resource would be the same. If we look hard enough, we can find exceptions (ACI subnets is a recent one), but they are rare enough to take on a case by case basis rather.

@et1975
Copy link
Contributor Author

et1975 commented Mar 3, 2023

I was referring to Farmer DSL changes - adding/removing a required param, changing the type used in the DSL in breaking manner, CE keyword renames, etc. My thinking was as we find better abstractions the breakages are unavoidable.

The breakage happening as result of changing to a new resource provider version are interesting too, but seem different.
The guidance from ARM is to keep the api-version on the provisioned resource, which is obviously a concern the DSL library like Farmer should be able to reflect.

@ninjarobot
Copy link
Collaborator

It definitely adds a lot of complexity to be able to emit different versions based on features, probably an unsustainable amount. Here's an example where I did this for container groups due to their breakage, and this is difficult to test and maintain. I did that because it was a unique exception, and while it's not elegant, even something cleaner would lead to a huge and tedious testing process to test the ARM resources emitted for different API versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants