What are composite actions and workflows?
For one of my projects I used Github Actions for our CI/CD, which provided me with two fundamental ways of organizing our pipeline code - workflows and actions. What's the difference between them?
A workflow is a configurable automated process that will run one or more jobs.
A composite action allows you to combine multiple workflow steps within one action.
In general, both approaches allow you to create reusable pipeline code, following the DRY (Do not repeat yourself) principle and combine related actions into one flow. From these quotes it is hard to determine which approach you should choose. If you want to get a quick overview - feel free to jump down to summary in a table and conclusion. Meanwhile, we will take a closer look.
Let's take create a composite action and reusable workflow, then investigate the differences:
You can copy these snippets or fork my repo. Let's run the trigger workflow from main branch:
Storage and folder structure
Storage and folder structure differ for the two approaches. When using a composite action, you need to create a separate folder, and the action file must always be named action.yml
. On the other hand, workflows can be named freely and stored in the workflows
folder.
If you aim to make actions or workflows reusable across multiple repositories, you have the option to publish them publicly. This allows other users to leverage your actions or workflows. However, if you have a Github Enterprise plan, you can create a private repository specifically for reusable actions or workflows, which will be shared only within your organization. This provides a more controlled and restricted sharing mechanism.
Calling
We call a composite action as a step inside a job and we should always checkout from repo, otherwise there will be an error.
When we call a reusable workflow, we "replace" the job in a workflow with this workflow and there is no need to check out.
Secret management
Reusable workflows can inherit secrets from caller workflow, also github
context is shared between them. If you want to use secrets in composite action, you have to pass them as inputs or ENV-variables.
Jobs and paralleling
You can parallel jobs in a reusable workflow, but you can parallel steps in a composite action. Composite action is a sequence of steps and can't use jobs inside.
Logging and timing
Github Actions' interface shows you the sequence of steps executed and their timing. If you are using a resuable workflow, each step inside workflow is timed a displayed separately:
Composite action is timed and displayed as one step, making tracking of pipeline's performance harder:
If you put importance in maintaining quick and transparent pipeline execution, this difference might be vital for you, as it was for me.
My story
When I started refactoring the pipelines, I switched to composite actions, because mostly the code I extracted seemed to be like a complex step, rather then a job. Since the project's frontend resided in a monorepo, pipeline timing was an important metric. As the codebase grew with more applications, I encountered an issue when our pipeline execution time exceeded a critical threshold of eight minutes and started investigating, where the bottleneck was.
As I dived into logs, Iunderstood, that wrapping steps into composite actions was a mistake. It was impossible to understand what is taking longer, unit tests or build time, when they are both timed as one step.
I rewrote everything that was vital for timing and now I have a better understanding of where there is room for improvement in our pipeline because we are timing and collecting the stats for each step. There still are some composite actions, but they combine only lightweight steps.
Summing up the differences:
Conclusion
In general, both reusable workflows and composite actions provide pretty much the same functionality. The main difference is in logging output, secret management and syntax, that you should keep in mind. If you know, that your pipeline might become a bottleneck you will need to improve, then go with reusable workflows for heavy tasks.
Top comments (0)