-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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] Use actionlint to parse Actions workflow files instead of act #24603
Comments
Originally posted by @ChristopherHX
|
I assume by js parser he means one in https://github.com/actions/languageservices which might be useful for validating before commit? Regarding ignoring case - it's changed on main branch of actionlint, but not yet released. |
Yes I mean that repo by js parser. You would have to add the
it inserts a mapping into a mapping from an expression result. Due to limitations of the workflow validator values on the right side may have to be expressions instead of a yaml mapping. Yes I read the source code of action/runner carefully, it is somewhat documented there. on: push
jobs:
_:
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
include:
- os: ubuntu-latest # Only ubuntu-latest has an extra env var MYVAR
env:
MYVAR: myval
MYVAR2: myval2
env:
SOME_ENV: B
${{ insert }}: ${{ matrix.env || fromjson('{}') }}
runs-on: ${{ matrix.os }}
steps:
- run: env This example won't work in nektos/act. insert has been implemented under BTW this |
Here are the references of the actions/runner:
However that example still uses azure pipelines yaml syntax |
Seems like action lint doesn't validate workflow keys of expression enabled objects. So it doesn't make In Github Actions is the following also possible ( Actionlint handles this one perfectly fine on: push
jobs:
_:
strategy:
matrix:
include:
- os: ubuntu-latest
env:
MYVAR: myval
MYVAR2: myval2
env: ${{ matrix.env }}
runs-on: ${{ matrix.os }}
steps:
- run: env However doesn't parse on: push
jobs:
_:
strategy:
matrix:
include:
- os: ubuntu-latest
key: MY_ENV
value: MY_VAL
env:
SOME_ENV: B
${{ matrix.key }}: ${{ matrix.val }}
runs-on: ${{ matrix.os }}
steps:
- run: env All in all Actionlint is pretty good, while having it's own parser. |
It does when a expression linter rule is applied, but that's after parsing and we have no reason to use it. Since you probably know - when are expressions expanded? Taking your example: on: push
jobs:
_:
strategy:
matrix: #this is loaded before env
include:
- os: ubuntu-latest
key: MY_ENV
value: MY_VAL
env: #I assume loading env resolves the expressions server side?
SOME_ENV: B
${{ matrix.key }}: ${{ matrix.val }}
runs-on: ${{ matrix.os }} #Same here
steps: # And all steps are probably ignored on a server and resolved on the runner?
- run: env |
Isn't it enabled by default in the online playground? I only see errors and syntax highlighting about expressions in yaml values (not keys).
Yes and this is server side expanded, then the strategy is expanded to a list of sibling jobs. However the whole strategy key is an expandable expression. Including all keys and values of sub objects. The last time I looked at the Gitea Actions code, this is not expanded.
No, the runner side expands the expression. The runner get's a list of parsed MappingToken of each workflow level. I reused actions/runner to enable GitHub Actions on my Gitea Server in 2021. However it has flaws with securty, db support and webpage design.
yes this is server side, Gitea Actions is expanding it somehow already on the server before scheduling the job You can look at the log of my GitHub Actions Emulator to see, when which expression is expanded on the server side. The order of some fields doesn't matter while expanding expression, while it is important for other fields. |
I was tinkering with this for a long while and have some "drafts", though I haven't tested them at yet. I got stuck (unsurprisingly, and multiple times) at making a jobparser version based on actionlint. Currently, I'm stuck at the following: As far as I know, gitea splits the job when the workflow is triggered and inserts the number of runs into the database. This works for simple jobs with no matrix. If the matrix is expanded into more jobs (or runs however you call them) we get more entries. I'm thinking about something like this:
Here is a rough concept I have: Make a middle layer in the database. Idea being that since the job!=run, we can split them into separate tables (one-to-many relations): Parsing workflow would create a finite amount of jobs equal to the jobs in the workflow - I don't have any concrete proposal for the layout of such table, but it could just be a storage for the job metadata (is it a matrix job, is it finished, what permissions would it need, concurrency markers, etc.) kinda like it's now except it's not used for actual runs of the job. There are a lot of issues with this that I can think of:
If it was possible, I'd like to combine this move with outsourcing steps to the runner #24604 - to avoid even thinking about how to port step generation to this. Alternatively, we could try to insert the job with the matrix and later expand it... but I feel like this would end up being more complex to track. I'm open to different/better ideas though. Maybe someone here sees a less complex way of handling this. |
This idea was inspired during a discussion with the nektos maintainers team.
Background
Act runner depends on act to run jobs, as act provides the necessary infrastructure. However, Gitea also depends on Act because Gitea needs the models defined in Act to parse workflow files and assign tasks.
For example, Gitea needs to extract
on
from the workflow file to decide which event to trigger, and alsoruns-on
of jobs to match runners.Unfortunately, the models defined in act are not incomplete because some fields do not matter when running workflows locally (which is what act is designed to do), such as permissions and concurrency.
Solution
If we add full syntax support to
act
or other packages, we would be reinventing the wheel, because actionlint has already done it.Although actionlint could be used as a command-line tool, it is also designed as a library. See the document which describes how to use actionlint as a Go library. Actually,
act
imports it too.So we could replace act in Gitea with actionlint to parse workflow files.
Possible difficulties
The forked act has a new package
act/pkg/jobparser
to split jobs in single files. LikeThis is for distributing jobs to multiple runners. The jobs may run on different platforms and run concurrently.
It may be difficult to do it again with actionlint. A half-baked idea of mine is:
IIRC, act supports specifying job but not matrix. So, there may be more work to do.
The text was updated successfully, but these errors were encountered: