64 bit mac apps no longer work. 2020 has been a tough, frail year. Last week, I joined many people who were laid off. Still I’m grateful for the good things that came out like Dreamland and CI with GitHub Actions for Ember Apps.
With GitHub Actions, I cut down CI runtimes for work projects to 3-4 minutes (with lower variance and more tests since March). I also noticed more and more Ember projects switching to GitHub Actions so I felt like a pioneer.
Today, I want to patch my original post and cover 3 new topics:
- How to migrate to v2 actions
- How to lower runtime cost
- How to continuously deploy (with ember-cli-deploy)
Enter the caverns and mines beneath the city of Torchlight and fight for the precious ember, the source of all magic. Explore the environments provided for missions and encounter various creatures to fight and then loot their bodies for equipment, weapons, and money. Torchlight 2.2 for Mac is available as a free download on our application. First things first: the app has replaced Realmac’s popular LittleSnapper software. Now, Ember is a totally new program with many more features and advanced capabilities than LittleSnapper. However, LittleSnapper fans may feel a bit bummed that Realmac has pulled LittleSnapper from the Mac App Store following the Ember launch.
I will assume that you read Part 1 and are familiar with my workflow therein. Towards the end, you can find new workflow templates for Ember addons and apps.
1. How to Migrate to v2 Actions
In Part 1, you met 3 actions that are officially supported by GitHub:
You can check out the README to find new features and improvements in v2. If you followed my workflow, you should be able to use v2 without a problem.
Notice that
actions/cache@v2
allows caching multiple things in one step. As a result, the cache retrieval step (line 29) is simpler.2. How to Lower Runtime Cost
I neglected to warn cost last time. For private repos, where production apps are likely stored, GitHub Actions charges you by the minute. 2020 taught me that money doesn’t grow on trees.
You can control 3 things to lower cost:
- Set operating system
- Lower job runtime
- Lower
timeout-minutes
Even if your repo is public and immune from charge, I recommend the last 2 practices to lower the overall runtime.
a. Set Operating System
In Part 1, I suggested that you can use
matrix
to test the app against various operating systems. I must redact because jobs that run on Windows and Mac cost 2 and 10 times as much as those on Linux. The rate difference also applies to storage used by GitHub Actions artifacts, which we will soon leverage.Unless you have a compelling business requirement, run jobs on Linux only:
b. Lower Job Runtime
When a workflow runs, you pay for the sum of all job runtimes. You don’t pay for the workflow runtime (except in the sense of feedback loop).
Our workflow has 1 lint and 4 test jobs. Suppose these jobs took 1:40, 3:20, 4:00, 4:30, and 3:40 minutes to run. In total, the jobs took,
We round up that number, then multiply by the per-minute rate ($0.008/min for Linux) to arrive at the cost:
14.4 cents seem trivial until you realize that your team can make hundreds or thousands of commits each month. (See Part 1, Section 1c to learn more about configuring
on
correctly.)There’s a silver lining for Ember developers. The predominant jobs in our workflow are tests. A test job takes a while to run because it needs to build the app. What if you can build the test app once and pass it to each job—a form of caching?
Since 2015,
ember test
has let you pass --path
to tell there’s a pre-built dist
folder somewhere. You can set the location thanks to 2 officially-supported actions:Even better, the
--path
flag works with ember-exam and @percy/ember. Here is a simplified update:Notice the use of
needs
(line 17) to indicate a dependency among jobs. All test-app
jobs won’t start until the build-app
job has finished.Although the workflow performs 1 additional job, the total runtime can be less because tests can finish sooner. When I introduced this change at work, I saw a 33% decrease (6-8 minutes) in billable minutes. That’s 50% more runs for the same cost.
The last thing to note is, we must build the Ember app in the test environment (line 7). The default
build
script makes a production build so I wrote build:test
to make a test build. If you pass a production build, the tests won’t run and will eventually time out (in CI and locally):c. Lower timeout-minutes
GitHub Actions doesn’t emphasize the need to set
timeout-minutes
. It’s how long a job can run (stall) before GitHub Actions cancels the workflow. You’re still charged for the run so it’s important to know that the default timeout is 360 minutes (!!).In short, if a workflow is to fail, let it fail fast. Make sure to set a low
timeout-minutes
for each job:A good initial value is how long build, lint, and test take locally, plus some wiggle room. Over time, however, you will want to observe runtimes and calibrate timeout.
To help you make a data-driven decision, I created inspect-workflow-runs. The script finds past runs and recommends timeout based on 95% confidence interval:
Speaking of failing fast, GitHub Actions lets you cancel in-progress jobs if any
matrix
job fails. This may be useful if you use ember-try or cross-resolution testing.3. How to Continuously Deploy
In Part 1, I mentioned auto-deployment with Heroku. Since then, I got to deploy Ember apps to GitHub Pages and Netlify thanks to open source work. I became curious about deploying apps from a GitHub Actions workflow.
The Ember community has a dedicated addon called ember-cli-deploy. It has several plugins so that you can customize the deployment pipeline. Afterwards, you call
ember deploy production
, which you can certainly do from a workflow. The hard parts may be building the pipeline and passing your credentials.As a concrete example, we’ll look at deploying to GitHub Pages with the plugin ember-cli-deploy-git. I’ll cover a basic setup and 2 ways to pass credentials. You can review the changes to ember-octane-vs-classic-cheat-sheet to see an implementation.
As for deploying to Netlify, although there is a plugin, I’d use the standalone ember-cli-netlify for simple static sites. Netlify can listen to a push to the default branch (similarly to Heroku) so we just need something to handle routing. You can review the changes to ember-container-query.
a. Setup
Step 1
We’ll deploy the app to the
gh-pages
branch. After we create the branch,we ask GitHub Pages to build the site from
gh-pages
.Step 2
Let’s come back to the default branch. We need to install a few addons:
The command will create
config/deploy.js
. For now, we can leave this file alone. We’ll look at it later in the context of setting credentials.Do update
config/environment.js
so that GitHub Pages understands the routing of the app:Step 3
Finally, create a
deploy
script in package.json
.Now, we can run
yarn deploy
to deploy the app from the local machine. Let’s look at how to deploy from the workflow next.b. Create a Deploy Key
We can’t simply add a step that runs
yarn deploy
because GitHub Actions will ask for authentication. When everything is meant to be automated, how do you authenticate?One solution is to check the public key against a private. We can store the latter as a secret environment variable for the workflow, much like we had with the Percy token. The authentication details are hidden thanks to the ember-cli-deploy-git-ci plugin.
Step 1
Install the plugin and generate a key pair.
The public key (
deploy_key.pub
) belongs to Deploy keys in the repo’s Settings page. The private key (deploy_key
) goes to Secrets and becomes an environment variable called DEPLOY_KEY
.After saving these keys in GitHub, please delete
deploy_key.pub
and deploy_key
so that they won’t be committed to the repo.Ember Mac App Download Windows 7
Step 2
We update
config/deploy.js
to indicate the presence of an SSH key:Step 3
Finally, we add a deploy job to the workflow. We can use
needs
and if
to describe when the app should be deployed (e.g. when there is a push to the main
branch).Here’s a simplified update:
c. Reuse Auth Token
Thanks to
actions/checkout@v2
, there’s an easier way to authenticate—one that doesn’t require ember-cli-deploy-git-ci
.While a job runs, the checkout action persists the auth token in the local git config. As a result, we can set GitHub Actions as the user who wants to deploy the app, but pass our auth token instead:
Last but not least, we provide an HTTPS URL in
config/deploy.js
.4. Conclusion
Thanks to shared solutions in Ember (the Together Framework) and new features in v2 actions, we saw that CI/CD with GitHub Actions continues to work well for Ember apps and addons.
We should watch out for long-running jobs because they cost money (even for public repos in the forms of feedback loop and developer’s time). In Part 1, we learned to save time by running tests in parallel and caching
node_modules
. In Part 2, by building the test app once and employing a fail-fast strategy.If you haven’t yet, I hope that you will give GitHub Actions a try and share what you learned. I look forward to discover more ways to optimize and enhance workflows.
5. Notes
A few sections in Part 2 were possible thanks to the Ember community:
- Dan Knutsen showed me how to pre-build the app for tests.
- Katie Gengler created the pre-build example in ember.js and directed Dan to it.
- Jen Weber walked me through how to use
ember-cli-deploy-git
. - Jan Buschtöns and Dan Freeman found a way to continuously deploy to GitHub Pages without
ember-cli-deploy-git-ci
. They shared their solution on Discord.
Katie kindly informed me that it’s also possible to pre-build an addon’s demo app for every
ember-try
scenario. (I wanted to test an addon at different window sizes.)Katie recommends caching
dist
(with a unique hash based on Node version, scenario name, and lockfile) over uploading it as an artifact. This is to avoid the possibility of passing the wrong dist
to a scenario.I posted new workflow templates on GitHub Gist.
- Ember addons: yarn, npm
- Ember apps: yarn, npm
If you are interested in cross-resolution testing, I recommend studying the workflow for ember-container-query.
![App App](/uploads/1/3/4/2/134261017/264944113.png)
Installing Ember is easy! And our new install process includes Ember CLI, Ember's build tool
- State of the art asset management (including combining, minifying, and versioning)
- Built-in generators can help you create components, routes, and more (and their test cases!)
- A standard project layout. Working on other Ember apps is easy, they're organized similarly
- Native JavaScript modules to keep your project organized
- A complete testing framework (unit tests, integration tests)
- Access to a growing ecosystem of Ember Addons. Add functionality to your app without writing a single line of code! They're already packaged up and ready to add to your app
Installation
Installing Ember is done using NPM. While you're at it we recommend you to also install phantomjs (if you don't have it already). Ember CLI uses phantomjs to run tests from the command line (without the need for a browser to be open).
Testing your installation
At this point, you should be good to go.. but we can test out your install to make sure everything works great.
Let's run the generator for your project:
Ember Mac App Download Windows 10
![Ember app mac Ember app mac](https://pic.macw.com/pic/202003/01101208_9853aa0afd.gif)
Ember Mac App Download Free
This will create a new
my-app
folder and generate an application structure for you.Once the generation process finishes, let's verify that we can launch the newly created app:
navigate to
http://localhost:4200
to see your new app in action.Troubleshooting
Got Node (and NPM)?
Run angular app on mac. Node Package Manager (npm) comes bundled with node.js and makes installing easy. If you're not sure if you have node.js installed, try running the following from your command line:
If the command works and you get back something like 0.10.x, you've already got it installed!
If you don't have it installed..
- Windows or Mac users can simply download and run the installer.
- Linux users can check out this great guide by Joyent for install instructions.
Once you've got node.js installed, re-run the above
node --version
to verify your install.