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

Proposal: VERSION entry #991

Closed
vladaionescu opened this issue May 19, 2021 · 2 comments
Closed

Proposal: VERSION entry #991

vladaionescu opened this issue May 19, 2021 · 2 comments
Assignees
Labels
type:proposal A proposal for a new feature

Comments

@vladaionescu
Copy link
Member

Background

One of the key reasons for using Earthly is the consistency in which builds are executed. While this is important, Earthly itself is under constant development and is evolving. By that definition, Earthly will evolve over time in the way it executes builds, and thus to some extent they will no longer be as consistent with the way a previous version of Earthly would produce results.

We need a way to pin the way an Earthfile is interpreted, to help maintain consistency, while allowing Earthly itself to continue to evolve.

Proposal

The proposal is to introduce a new VERSION entry at the top of every Earthfile. This version declaration must be the very first command in the Earthfile. This command would tell Earthly what version of Earthly the Earthfile is written for.

Example

VERSION 0.7

FROM alpine

build:
  RUN echo abracadabra

The version number would only specify <major>.<minor> and would always leave out the <patch> part of the semver. Earthly releases anyway maintain compatibility between patch version increments. Minor version increments take place when there is an incompatibility introduced.

If a version of Earthly previous to 0.7 encounters this declaration, it will return an error and not execute the build. If a version of Earthly greater (or equal) than 0.7 encounters this declaration, it will downgrade its capabilities to support the behavior the way it was specified in version 0.7.

Importing cross-versions.

Referencing other Earthfiles of different versions is allowed.

A 0.6 Earthfile can import a 0.7 Earthfile and vice-versa. The parser and interpreter need to be smart enough to support this.

Support lifecycle

If a version is too old, it will not be supported.

We aim to support at least 4 minor versions behind and also at least a whole year since the last release of that minor version. This should be a nice balance between keeping Earthly development nimble enough, while not breaking people's builds abruptly.

Rollout

At the time of writing the latest version of Earthly is v0.5.13. We plan to introduce VERSION as an optional declaration for the next 4 minor versions. If VERSION is not declared, it is assumed to be 0.5 so as to maintain backwards compatibility. From version 0.9 of Earthly onwards, VERSION will become mandatory.

Earthly Version Behavior
v0.5.13 VERSION not supported - not a recognized command
v0.5.14+ VERSION is optional. If VERSION declared is different from 0.5, return an error
v0.6.* VERSION is optional. If not provided, then 0.5 is assumed. If VERSION declared is <0.6, downgrade behavior to match. If VERSION =0.6 enable all features. If VERSION >0.6, return an error
v0.7.* VERSION is optional. Similar behavior to 0.6
v0.8.* VERSION is optional. Similar behavior to 0.6
v0.9.* VERSION is mandatory. If not provided, Earthly returns an error. Similar behavior to 0.6 otherwise

An example

Here's a realistic example. Take this change for instance: #896.

The change will be implemented internally with a feature flag to switch between the old and the new behavior. Because this change is backward incompatible, it will trigger an Earthly minor version bump to v0.6. Thus if an Earthfile contains the declaration VERSION 0.5 (or if it does not contain a version declaration at all, thus defaulting to 0.5), then it will use the old behavior of this feature. If, on the other hand, it contains a declaration VERSION 0.6, then it will use the new behavior of this feature.

Implementation

Behind the scenes, all compatibility breaking behavior will be feature flagged (we anyway do this part today). VERSION declarations merely map sets of feature flags to version numbers and enable/disable these according to an internal, hard-coded map.

The mapping will be available to Earthly end-users in documentation form.

The idea is that these kinds of changes will be infrequent enough so as not to create an explosion of possible combinations. But it also means that on making a breaking change we promise to maintain the old behavior for a while, to make sure we're not surprising our users.

TODO

  • How to maintain docs for the differences in behavior? Perhaps in the places where the feature is described, we include subsections about how the feature behaves in older versions. This way we don't have to maintain completely distinct docs branches.

Possible extension: enabling experimental behavior

As we develop new features, they go through various stages or readiness before being marked as GA:

Experimental -> Beta -> GA.

A feature is truly ready when it is in GA stage. But the feature is available for experimentation even before that. So the question is which version really enables the feature? The best answer is probably "the version in which the feature is finally marked as GA". However, we need a way to enable the feature while in experimental or beta stage, for preview purposes.

For this reason, we propose the extension of feature flags to the VERSION declaration:

VERSION 0.6 --feature1 --feature2

Where feature1 and feature2 are features in either experimental or beta stages that will be GA'd perhaps in VERSION 0.7. This type of declaration allows the user to enable these features in their current preview forms while interpreting everything else in the Earthfile as version 0.6.

And because these features are not yet GA'd, then this declaration will have fewer guarantees towards the backwards compatibility. If a v0.6.* Earthly interprets this, it might have an older experimental version of that feature, while if a v0.7.* Earthly interprets this, then it will have a final form of the feature, which may not behave the same as the way it was coded in its experimental form. So it's very much a "i know what I'm doing, please enable these experimental/beta features" type of declaration. By using feature flags the user is giving up some of the compatibility promises.

This helps users be more mindful about which features they are using that are finalized and which are still being experimented on.

@vladaionescu vladaionescu added the type:proposal A proposal for a new feature label May 19, 2021
@alexcb
Copy link
Collaborator

alexcb commented May 20, 2021

The one drawback to one day requiring the VERSION and subsequently saying we'll eventually stop supporting old versions is simple Earthfiles will still have to be maintained even if nothing inside them are changing. For instance our hello world Earthfile is desgined to be run as earthly github.com/earthly/hello-world:main+hello, it's just essential a FROM and a RUN and should work with all versions of earthly.

If we make sure we keep our example repos updated with the expected VERSION, then I don't really see this being an issue. Perhaps we just to need incorporate these repos into our tests (I think they already are).

Overall I think it's a decent idea (including the --feature flag).

@vladaionescu
Copy link
Member Author

The one drawback to one day requiring the VERSION and subsequently saying we'll eventually stop supporting old versions is simple Earthfiles

That's true. Hmm.. maybe it becomes mandatory in strict mode only?

Without it, it may be hard to figure out what it should default to. For now, it can default to 0.5. But for very far in the future Earthly versions, we probably don't want to maintain compatibility so far back. So perhaps what it defaults to might evolve from version to version. E.g. version v0.11.7 of Earthly might default to the earliest that it maintains compatibility with (maybe it's 0.7 at that time).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:proposal A proposal for a new feature
Projects
No open projects
Development

No branches or pull requests

2 participants