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

Extensions #105

Closed
wneirynck opened this issue Feb 27, 2024 · 3 comments
Closed

Extensions #105

wneirynck opened this issue Feb 27, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@wneirynck
Copy link
Contributor

Extensions are a way to link functionality to a job property. An extension follows the interceptor pattern: it has a "before" and "after" phase, both are optional. They have full access to the runtime. When including an extension dependency in deps.edn, you should also require it so it gets "registered". MonkeyCI will apply the extension when it encounters a key on a job for which that extension was registered.

We could set up caches and artifacts as extensions this way.

Possible additional features:

  • allow extensions to be run before or after other extensions, instead of just before/after the action.
@wneirynck wneirynck added the enhancement New feature or request label Feb 27, 2024
@wneirynck
Copy link
Contributor Author

How should we approach this? An extension is a function that runs before or after an action, or maybe those two functions combined. As an example, let's consider unit test results. We would like to display the test results to the user after they have run. In the Java platform, junit.xml is the most widely used format. It doesn't really matter, an extension could support multiple formats, or multiple extensions could be built for various formats. The sequence of events could be like so:

  1. The user configures in their build script that a job produces test results.
  2. When the job runs, it produces those results. Usually this is a file (but it could be something else, like stdout).
  3. The raw test results should be communicated back from the job (probably a container) to the build script.
  4. The extension is invoked, where it can access those results, process them and store it as a structure in the job results.
  5. Somehow those results should be displayed to the user, as a separate tab in the job details.

Several questions arise here.

  • How is the raw data communicated back to the build script, and so to the extension?
  • How should the structured information be displayed to the user?

Passing Information to Extensions

A logical and often-used method of passing data is using artifacts. The job declares an artifact that holds the test results, and the extension could be configured to know about this artifact. When the extension runs, it could use the API to download the artifact and access the contents. Since downloading artifacts should already be provided in the API, this does not require special permissions or coding. But it may not be the most efficient solution, passing the raw data directly may be easier, but it does create it's own problems. For instance, what happens if the raw data is very large? Like a dump file used to analyze memory consumption?

So, for sake of simplicity, let's just assume we'll use artifacts for this.

Displaying the Results

After the processed information is stored in the job, it should be available for displaying. But how should this be displayed? Ideally, the extension itself is responsible for this. Somehow the extension should the contain some frontend code for this? Or we need to provide a generic way to render information like this? Or should we allow the extension to generate html that is displayed directly in the GUI?

Including frontend code seems overly complicated, it would require defining some sort of "frontend api" for this. Since the frontend is centralized (i.e. not specific to the build script), this would also create security issues.

Generic rendering would only work if we, again, define some sort of contract that the extension should adhere to. The content could be provided as JSON or EDN and required to follow a certain format. This would be the safest way to go, and probably the most consistent (for the GUI), and reasonably easy (for the extension). It would be fairly inflexible though.

The third solution, rendering HTML is the most flexible. Extension writers would have full control over the resulting output. It would most likely lead to inconsistencies in the UI, and it would also pose security risks. What happens if the extension injects JavaScript in the output? We could put it in an iframe.

Conclusion

I think we should only consider the last two solutions, since the first would be too complicated and risky. The second is the safest albeit the most inflexible. But let's try it out and see if it is usable.

@wneirynck
Copy link
Contributor Author

See also issue #136

This was referenced Apr 26, 2024
@wneirynck
Copy link
Contributor Author

Backend has been implemented. Using it in frontend not yet. I have added some ad-hoc code to display test results, which is provided by an extension. I think we should stick to this for now, and add some generic way later on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant