Still exploring the syntax here a bit. The expectation is that blah() syntax
would actually be invoking macros which would simple expand out at parse/compile
time.
In this example, the `each` macro would create four different stage blocks.
Inside of those macro blocks, the keyword `it` is introduced to represent the
item which is intended to be substituted.
Each of those stage blocks have a name created using the`concat` macro.
None of the other blocks have parenthesis and take arguments the way the
stage(name) does. To make all blocks behave a bit more in line with one another,
this commit changes the behavior of naming stages to look more like a
generalized block settings.
This presages some macro work that's coming in the following commits.
This syntax makes it more clear the conditions not only that a stage can be
entered , but what conditions must be met in order for the stage to
exit/complete.
There's a slight nuance, which I am not certain at the moment is important with
'when' in the declarative Jenkins Pipeline syntax as it relates to 'enter' here.
The 'when' directive can be used to prevent a stage from being executed in a
flow, i.e. skipped. An "enter" however could mean "wait for this criteria to be met"
which might be confusing to a user, but I think this initial simplicity is worth
the experiment.
The "exit" is obviously a bit easier to understand, but where some nuance will
come later on is how we might determine/model what exit criteria should hold
onto cluster resources, versus a simple "listener" which requires no 'runtime'
In the context of the cache {} block, we don't want to use `from` to copy the
cache directives from another stage entirely, rather we want to "use" the named
cached entry.
I think it makes sense to allow caches to be pulled individually. Imagining a
case where a compilation stage might create multiple platform specific
directories or binaries. In such cases, a Windows test-specific stage would only
want to grab the cached entries for Windows, etc.
This of course comes with no actual implementation, but it at least provides a
grammar to start with. There's likely some cleanup in the rules and edge cases
that are missing, but this is a start.
There's a big question in my mind on how to express what requires a runtime and
access to the working directory, and what should live "outside" of that.
Still uncertain.
Including an example to help tinker with the user interface for modeling a
process for a mock heroku-based web application.
What's missing right now for sure is the concept of credentials and how those
might fit into the world. That will require more thought.
The syntax is at the moment heavily inspired by Declarative Pipeline from
Jenkins, but not actually compatible.