Goals:
- Create ticket workflow, convert notes to tickets
- Integrate CI into the project
Create ticket workflow, convert notes to tickets
Although I am working on this new project solo and for the foreseeable future, I still wanted to have a way to create and track tasks. Back in the day, I used waffle.io but that project appears to have been axed. I liked waffle.io because of its Github integration and because it was relatively lightweight. I've used Jira and Atlassian, but those project managers seemed a bit heavy-handed for what I needed. After digging around a bit and asking some colleagues I settled on Github's own Issues and Projects.
It seemed like a logical choice, the biggest win is that they are already a part of the repo, so its one less service I need to keep track of. It's also not any more complex than I need it to be, I can keep it lightweight and nimble. My current workflow is to first create an Issue ticket, mostly just a title, to get my thoughts documented. If I have notes at the time of creation I add them, if not I leave it blank. The order of the issue tickets is trivial, that's where Projects come in. Projects is basically a kanban board, like Trello, Jira, etc. My flow with the Project board is that I pull in 4-8 issue tickets at a time, so I can see a short runway, then move the ticket across the board as the task progresses.
I recognize that I'm using both Issues and Projects at their minimum capacity, but at the moment that serves my needs. After all, I can always expand and modify my workflow, but this is a good starting point. The list of Issues for my project can be found here, and the Project board here
Integrate CI into the project
This was a big one for me. A lot of the tutorials and walk-throughs I came across in Part 1 jumped from the creation of the project right into something like tweaking the CSS setup or generating the first migration. The longer a project goes on without incorporating some kind of CI (continuous integration), the bigger headache it is going to be to get the tests to pass. I feel like it's much better to get integration dealt with right out of the gate and hopefully never have to think about it again.
Github has made it a lot easier than I had remembered to setup CI. The entire process can be done in the through Github web interface by clicking Actions > New workflow
. Github suggests an Elixir-based workflow, clicking Set up this workflow
brought me to the Github editor, where it has a file named elixir.yml
setup to be added to a new folder structure:
./.gihhub/workflows/elixir.yml
This is what the default file looks like:
Referencing a tutorial, I went ahead and added a formatting check to the end of the file:
And committed the file via the Github web interface. At that point this was the entire elixir.yml
On the first run of that CI configuration I got an error that my tests weren't passing. I did some research and found that I needed to add some code to include a database for the tests to run on:
So, now the updated elixir.yml
looks like this:
With that database setup, the tests passed, and I had that very satisfying green dot next to the pull request. Currently the CI was confirming that my tests pass and that the code was formatted properly. I was also interested in a service to analyze the code for consistency. I accomplished this by adding Credo to the project. Once included in the mix.exs
file, Credo can be run locally with mix credo
and it can be incorporated into the CI by adding the following line to elixir.yml
:
I added the --strict
flag because I figure if I'm going to use a tool like this, I might as well use it to the fullest extent. With that addition, this is my final elixir.yml
file:
To my surprise, Credo actually found a few syntax errors in the Phoenix-generated code, so I ended fixing those and pushing up a small refactor commit to get the CI green again. It's worth noting that the compile time of Credo has slowed significantly with modern versions of Elixir, as noted in this issue. I'm not downgrading my Elixir version or doing anything to handle this, as it still meets my needs, and I have the time to wait for the checks to complete.
Bonus - Include CI Status Badge in README
One of the articles I was referencing through this CI work also included an example of how to include the CI badge in the repo's README. I mean, why not? It will be pretty gratifying to see that green CI tag every time I'm in my repo. As far as the markdown goes, it's basically an image tag, being linked to a Github-generated svg
. This is what my my image tag looks like:
I'll break it down, since it took me two commits to get it right:
A basic image tag in markdown is:
So, in the case of CI badge, the first chunk:
Is declaring that its an image, and the alt text is Elixir CI
. For what its worth, it would also work if the alt text were blank:
And the second chunk:
Is the source of the image file. The URL breaks down as such:
-
https://github.com/noelworden
-> my Github account -
/atlas
-> the project repo -
/workflows
-> the folder where the CI file is contained -
/Elixir%20CI
-> the CI file I'd like to see the status of- It should be noted that its necessary to use URI-encoding to include the space in the
name
field of the file
- It should be noted that its necessary to use URI-encoding to include the space in the
I didn't realize this until I had already coded it wrong once and merged it (🤦‍♂️), but that image link can be tested and confirmed in any markdown previewer.
Bonus - Create Pull Request Description Template
A pull request template wasn't any part of my original plan for this block of work, but I'm still figuring out my commit and pull request workflow. I had merged a handful of pull requests to get all of this CI work up and running correctly and realized that I should have been including the Issue number in the pull request descriptions. Knowing that I would forget to include that detail in future pull requests I figured it would be worth my time to incorporate a pull request template.
The file is a markdown file, that Github will look for when generating a new pull request. For Github to recognize it, the new file needed to be created and named:
PULL_REQUEST_TEMPLATE.md
This file can be stored in any of the following places:
- the project root ->
atlas > PULL_REQUEST_TEMPLATE.md
- in a
docs
folder ->atlas > docs > PULL_REQUEST_TEMPLATE.md
- in a hidden
.github
folder ->atlas > .github > PULL_REQUEST_TEMPLATE.md
In my original implementation of this template file I put it in the docs
folder. But, as I write this and am thinking about it more, Im going to move it to the .github
folder. The .github
folder already exists because of the implementation of the CI workflow, and it feels more appropriate to have this Github-specific file there than in a docs
folder.
In my case, I just wanted to ensure I always included the Issue number, so my template for the moment is simply one line:
But, of course, a template can as detailed as necessary for the given project.
Closing thoughts
With these four items complete, I feel like my project is in the realm of best practices. I can create and track tasks, have continuous integration setup, and have the ability to run a linter locally. I can also see the status of the project's continuous integration at a glance, and have a simple pull request template setup. Since I'm in the mode of laying the groundwork for the project, the next step will be setting up a hosting environment.
This is what my repo looks like at the end of this block of work.
References
- https://docs.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow#adding-a-workflow-status-badge-to-your-repository
- https://hashrocket.com/blog/posts/build-the-ultimate-elixir-ci-with-github-actions#setting-up-mix-dependency-cache
- https://lobotuerto.com/blog/elixir-continuous-integration-with-github-actions/
- https://docs.github.com/en/enterprise/2.15/user/articles/creating-a-pull-request-template-for-your-repository
This post is part of an ongoing series. I encourage any critique, feedback, or suggestions in the comments.
Top comments (4)
Hey amazing work, i've managed to setup the CI with your explanation it's super nice.
The only thing i would mention is that you've pasted the yaml file like 4 times and the last one is not actually the final version of it, as it's missing the previous step of adding the db docker.
The only way i would imagine you could improve this is by having 1 final one, and some small snippets in between.
Anyways awesome work!
Thanks so much for the feedback! I have posted an updated final yaml file. I know what you are saying about posting the file several times, it's tough trying to find the 'right' way to show a progression in the same file.
I'm happy you were still able to use this post to help setup your own CI.
I also really like GitHub's Project boards (like a Kanban board)... good recommendation!
My team and I fully use their tools: Issues, Milestones, Labels, and Projects to manage a complex project.
It's nice to have everything in one place, right?