In the previous blog post, we explored a basic use case of Taskfiles for build automation and developer workflow. In this post, I will cover some advanced workflows that help in maintaining common taskfiles across multiple projects.
As your development projects grow, you may find yourself repeating the same taskfiles over and over again in multiple repositories. This can be a waste of time and effort as you need to make similar changes in multiple projects, and it can also lead to errors and inconsistencies.
The team I worked on also had a similar situation, to overcome this, we created a Git repository called
templates where we store our taskfiles which are common to almost all our projects (for common tasks like, build, setting environment variables, helm, docker and other commands).
Once we created a common repository, we started splitting up our common tasks into multiple files like
go.yml etc., After splitting up our taskfiles, our git repository looked like this
├── README.md ├── taskfiles │ ├── docker.yml │ ├── env.yml │ ├── git.yml │ ├── go.yml │ ├── helm.yml │ └── vagrant.yml └── vagrant ├── Vagrantfile └── devenv_customization.sh
Since we were using Vagrant to set up our development environment (both Windows and Mac) as the same, we used Vagrant. But this is a topic for another blog :)
Anyway, we stored our multiple taskfiles in a folder named
taskfiles. Once our repository was prepared, we proceeded to the individual repositories of our services and added the common repository as a Git submodule by executing the command mentioned below. (This command only needs to be run once, and then we'll commit the changes to our current repository so that we don't need to run it again.)
git submodule add https://github.com/<repo url> templates
Once we run this command, a new folder called
templates will be created and all our files from the common repo will be present here.
Now, it's time to incorporate these common Taskfiles into our service repository. Create a new file called Taskfile.yml in the root directory of the repository and import the Taskfiles as described below.
version: 3 ## add tasksfiles as per the project requirements includes: go: taskfile: templates/taskfiles/go.yml optional: true docker: taskfile: templates/taskfiles/docker.yml optional: true helm: taskfile: templates/taskfiles/helm.yml optional: true tasks: submodule: desc: "Update submodules" cmds: - git submodule update --init --recursive --remote --merge default: desc: "Default task" cmds: - task --list-all
In this example, we have imported the necessary taskfiles for this project using the "includes" keyword. Additionally, we added a task called "submodule," which will be utilized when someone clones this repository and wants to retrieve files from the common repo into the
Now that everything is set up, it's time to give it a test run. Execute the task command in the terminal, and you will see that all the tasks from the imported taskfiles are displayed in the terminal.
❯ task task: [default] task --list-all task: Available tasks for this project: * default: Default task * submodule: Update submodules * docker:build-image: Build Docker Image * go:build Build the golang application * helm:up Deployes the helm chart * helm:down Deletes the helm deployment
Voila! Everything works as expected. Now that we have imported all the tasks into our repo's Taskfile, we can run commands like
task helm:up, etc.
This method worked great for our team to clean up the clutter of common tasks in the Taskfiles of multiple repositories. By storing them in a single place and using them only where needed, we've streamlined our workflow.
In this blog post, we discuss advanced workflows for maintaining common Taskfiles across multiple projects using a Git repository called templates. By splitting common tasks into separate files and incorporating them as Git submodules, we streamline the development process, reduce repetitive work, and minimize errors and inconsistencies. I hope you find this blog helpful to implement common taskfiles in your project too :) See you in my next blog. Until then, Happy Coding!