5 Ways to DevOps-ify your App - Github Actions Tutorial
one of the best ways to increase
productivity in a software project is to
automate anything manual or repetitive
and you might be surprised at how easy
automation is to implement when you use
an awesome tool like github actions in
today's video we'll look at five
different techniques that can improve
the quality of your code and make your
life more productive through the magic
of DevOps if you have no idea what terms
like continuous integration and delivery
mean you will by the end of this video
and if you choose to follow along with
your own project we will automate the
hell out of it if you're new here like
and subscribe and grab the full write-up
from fire ship IO before we get started
I'd like to take a second to say thank
you because the channel just surpassed
three hundred thousand subscribers to
celebrate that I have a big giveaway
plan in the next 100 seconds of code
video that everybody can participate in
stay tuned for that in a couple days
pending the apocalypse now to get
started with today's video the only
thing you really need is a github
repository and the service has a very
generous free tier so don't worry about
paying for anything upfront now Before
we jump into these five different DevOps
recipes let's answer the question of
what is github actions consider a repo
on github there are all kinds of
different events that can happen to that
repo someone might start the repo send a
pull request or you might merge code
into the master branch these are
examples of events and any event can
trigger an automated workflow a workflow
can spin up one or more containers for
you in the cloud then you provide a set
of steps or instructions for the
container to do something useful for you
github will log the progress of each
step and make it very clear if something
failed now the really cool thing about
actions is that instead of writing your
own steps from scratch you can use ones
implemented by the community you can
think of each step as a reusable chunk
of code which we call an action on
github you'll find hundreds of reusable
actions that solve common problems with
each one being its own git repo that you
can fork and customize as needed but I
think the best way to get started is to
look at some real-world examples a good
starting place is continuous integration
and if you have no idea what that term
means make sure to check out my 100
seconds of code video on that topic the
whole idea behind continuous integration
or CI is to have developers submit their
code to the main codebase and small
maintainable chunks usually on a daily
basis and those changes should be
automatically tested against the main
codebase let's take a quick tour of the
code inside the package.json you can see
I have a set of scripts here we use just
to run
automated tests and then build to build
the app with webpack the app itself is
just a simple website that tells you
what day of the week it is inside the
source directory we have app KS with a
JavaScript function that implements that
logic and then we have apt SJS to test
that logic
feel free to clone this repo if you want
to use it as an example or better yet
use your own project as a starting point
because these principles apply to any
github repo when you visit your code on
github
you'll notice this actions tab this is
where you can monitor your workflows
when a workflow is triggered it will
give you a log of everything that
happened on the server what we want to
do for continuous integration is have
our test suite run anytime there's a
pull request to the master branch if the
test suite fails or if the code fails to
build we should get a red checkmark here
automatically telling us not to merge
that pull request but if everything goes
according to plan we should get a green
check mark now back in the source code
you can see I have a github directory
followed by workflows and a file called
integrate gamal anything in this
workflows directory will be picked up by
github and automatically set up as a
workflow in the cloud the gamal file is
where we define the workflow we'll give
it a name of node continuous integration
then we need to tell it on which event
or events to run we do that with the on
object and in this case we want to run
it on pull request to the master branch
now every workflow should have one or
more jobs you define them on this jobs
object and then first give the job a
name we'll call this one test pull
request from there we need to tell the
job which VM to run on I'll run this one
on Ubuntu but you also have the choice
of Windows and Mac OS next we need to
give this job a set of steps or
instructions that actually build and
test our code well first want to get our
source code into the virtual machine we
can do that using an officially
maintained action called check out that
brings your source code into the current
working directory and that means you can
run commands like you would from the
command line if working on the project
locally but in our case we also need to
set up nodejs in order to run those
commands so we use the node setup action
and then specify the version and from
there we're ready to start running our
own commands we first need to install
all of our dependencies from NPM and we
can do that using the CI command
that's equivalent to NPM install but it
does a clean install for your CI server
from there we'll run our test command to
test our code and then after that we'll
run our build command to make sure the
bill
compiles properly now it's also worth
noting that if you have a more complex
test suite like end-to-end tests with
Cypress for example there's very likely
an existing action to set up the test
runner for you automatically in the
environment and that's all it takes for
the workflow configuration to start
using it
we just need to commit it to the master
branch I'll run git add git commit and
then get push to push that to the remote
repository now if you go to the actions
tab on github you'll notice that it's
still empty that's because we haven't
had an actual pull request event to
trigger a workflow so let's go ahead and
give our workflow a spin by creating a
pull request I'll go ahead and create a
new branch using git checkout with the
be flag to automatically move into it
inside that branch
I'll make some changes to the source
code that cause the test to fail I'll
then commit those changes and then push
this branch to the remote repo when I go
back to github I'll see the option to
create a pull request which I'll go
ahead and do and you'll notice that it
indicates how we're running checks or a
continuous integration test in the
background if we go to the actions tab
we can see logging for this process
running in real time in this case the
tests on the pull request fail which
means we probably shouldn't integrate
this code into the main code base and as
the developer who submitted this code I
can look at the logs and realize what I
did wrong in this case since I have an
open pull request I can go back into my
code and fix it and then push another
commit to this branch github will
automatically rerun the workflow because
this is an open pull request and this
time around we get green checkmarks so
that takes care of our continuous
integration now it's time to move on to
the next phase continuous deployment at
this point we're confident we have a
valid pull request and when we merge
that code into the master branch we also
want to deploy the app to our customers
so continuous integration is about
merging new code into the code base
while continuous deployment is about
pushing that code out to your customers
to demonstrate this I'm going to
integrate a third-party host
firebase and I'd like to give a shout
out to mark stammer Johan he put
together an awesome guide that will take
you through each one of these steps so
make sure to check that out on fire ship
IO we can easily set up hosting locally
by running firebase init hosting then we
can push our code to our firebase
hosting account using firebase deploy we
can do all this locally because we're
authenticated into our firebase account
on our local system but how do we
authenticate a remote CI server to do
the same thing what we'll need to do is
share a secret token with github we can
obtain that token from fire
by running fire-based login.c I this
will return us with a token string which
you can think of as an API key or user
name/password combination make sure to
keep this value secret go ahead and copy
the value from the command line and then
head over to your github repo go to
settings and secrets and add a new
secret we'll give it a name of firebase
token in all caps and you'll want to
make sure to use that same name then
we'll paste in the token and save it
github will automatically encrypt this
value for us and then we can access it
securely from our CI server in other
words it gives us a way to securely
authenticate with firebase from a github
actions workflow now let's go ahead and
create another gamal file in the
workflows directory this one we'll call
it deploy instead of running this
workflow on a pull request we'll run it
on a push to the master branch so this
workflow will run if we push code
directly to the master branch or if we
merge a pull request into it now the job
itself looks almost identical to the
previous job we check out the code setup
node run our build command but then we
need to deploy it and to do that we're
going to use a third party action called
the firebase action this action takes
care of all the steps required to setup
the firebase CLI on your server it will
run the firebase command and then we
tell it to use the arguments of deploy
only hosting and it's going to be
looking for an environment variable of
firebase token we can access our secret
github value by using dollar sign double
braces followed by Secrets dot firebase
token and that's basically all there is
to it we can start using this continuous
deployment workflow by pushing it to the
master branch now if we go back to
github and merge that pull request from
the previous example you can see from
the login that it automatically builds
and deploys our code to firebase and the
changes should be automatically
reflected on the website itself and now
that we have a basic CI CD pipeline I
want to look at some other cool things
you can do with github actions that you
might not realize personally I maintain
a few open source projects that are
available as libraries through NPM one
of those projects is spelt fire and
anytime there's a major code change on
the master branch we cut a new release
so developers can use that code in their
projects and every time that happens I
also need to go to the command line
login to NPM and push that code to the
NPM registry it's kind of annoying and
easy to forget so let's just automate it
with github actions and this workflow
you'll notice I'm using the release
event that's because not every code
change on the master branch work
is a new release for example if you just
fix a typo in the readme it doesn't
require a whole new release to be pushed
out to NPM in this recipe you'll notice
we have two jobs one for build and one
to publish to NPM and we might want an
additional job to publish to the github
package registry by default all the jobs
will run concurrently in parallel but
that's not actually what we want here
because we want to first build our code
before releasing it to the package
managers we can use the needs keyword to
tell github actions to run this job
after the previous job is finished this
can be a really useful technique because
in our case here it allows us to build
the code once and then push it out to
two different registries without having
to rebuild the code so that's really
useful if you're a library maintainer
but most companies use a lot of other
communication tools beyond github like
slack disk or JIRA Trello and so on and
in most cases these tools maintain
github apps for you to integrate with
their tools directly in github when you
go to the github marketplace you'll
notice that it's separated by apps and
actions actions are reusable pieces of
code you use in your own workflow while
apps are fully pre-built solutions that
don't require you to deploy any code
whatsoever because we use slack for fire
ship IO I'm going to use that as an
example let's imagine that I wanted to
receive a slack notification every time
a new github issue is posted there are a
variety of community maintained actions
that allow me to do this easily in a
workflow in this workflow you can see I
set up a trigger for github issues then
use a slack action along with some
configuration variables to have it post
messages directly in my slack channel
every time there's a new issue on github
that's cool in all but you can also
solve this problem using a github app
and it can be installed on your account
by simply clicking a few buttons the
nice thing about a github app is that it
can be used across multiple repos
simultaneously so when you're automating
with github actions it's a good idea to
ask yourself if you want a fully
installed app or if you want to build
your own workflow with actions I may do
a whole separate video on apps because
there's a lot of cool things you can do
like automatically analyze code quality
automatically update your dependencies
automatically optimize all your images
and automatically do a whole bunch of
other cool stuff but now let's shift
gears into the final recipe which is a
github action that runs on a specific
schedule this one happens to be a
special treat for firebase users because
it solves a common problem how do I
export my firestore data on a regular
basis currently if the database doesn't
provide automatic backups so you need to
man
export your data in order to reimagine
this recipe we use the on schedule event
and pass it a cron schedule if you don't
understand how this cron syntax works
don't worry
not many people do but there's an
awesome app called crontab guru that can
automatically generate schedules for you
the schedule in this example runs every
night at midnight and then in the action
itself we're using an action maintained
by a Google cloud platform this action
sets up the G cloud CLI in the
environment and then we can use it to
run a couple commands to export our
firestore data into a storage bucket and
that process is now fully automated so
we should hopefully never have to worry
about it again and check the links in
the description for a full write-up on
how to set up the service account and
everything else involved with G cloud
I'm gonna go ahead and wrap things up
there hopefully this video helped you
get started with automation in your own
project and let me know what kind of
things are using github actions for in
the comments stay tuned for the giveaway
video in a few days thanks for watching
and I will see you in the next one
[Music]