The final step to enable continuous delivery from CircleCI to all your early adopters is to add some commands to the .circleci/config.yml
file we created earlier.
Export login capable of pushing this snap
The first thing we need to do is export a login so that the Snapcraft running in CircleCI can authenticate as us, thereby gaining permission to actually upload this snap (note that this feature requires at least Snapcraft v2.37, which at the time of this writing is only available in the beta
channel of the snap):
$ snapcraft export-login --snaps hello-kyrofa --channels edge --acls package_upload credentials
Enter your Ubuntu One e-mail address and password.
If you do not have an Ubuntu One account, you can create one at https://dashboard.snapcraft.io/openid/login
Email: email@example.com
Password:
Login successfully exported to 'credentials'. This file can now be used with
'snapcraft login --with credentials' to log in to this account with no password
and have these capabilities:
snaps: ['hello-kyrofa']
channels: ['edge']
permissions: ['package_upload']
This exported login is not encrypted. Do not commit it to version control!
Using this command, we exported a login whose capabilities are limited to uploading a new revision of the hello-kyrofa
snap, and only releasing to the edge
channel. Take heed of the final warning, however: this exported login is not encrypted, and should not be placed directly into our repository. Let’s encrypt it, first:
$ sudo apt install openssl
$ openssl aes-256-cbc -e -in credentials -out .circleci/credentials.enc
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
Now you have your exported login safely encrypted with the password you selected in .circleci/credentials.enc
. You should now remove the unencrypted version:
rm credentials
Note that this exported login by default is only valid for a year. Once it expires you’ll have to do this step again to refresh it (export it and encrypt it using the same password).
We need to be able to decrypt this file in CircleCI, so open up your project’s settings. Under “BUILD SETTINGS” select “Environment Variables” and then select “Add Variable”

Create a new variable named “SNAPCRAFT_CREDENTIALS_KEY” and set its value to the password you used to encrypt the .circleci/credentials.enc
file above, then select “Add Variable”.

Fill out .circleci/config.yml
Now open up your .circleci/config.yml
file and make it look like this:
defaults: &defaults
working_directory: ~/workspace
docker:
- image: snapcore/snapcraft:edge
version: 2
jobs:
build:
<<: *defaults
steps:
- checkout
- run:
name: Update index
command: apt update
- run:
name: Build snap
command: snapcraft
- persist_to_workspace:
root: ~/workspace
paths: ['*.snap']
release:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: ~/workspace
- run:
name: Install prerequisites
command: |
sudo apt update
apt install -y openssl
- run:
name: Decrypt credentials
command: |
openssl aes-256-cbc -d \
-in .circleci/credentials.enc \
-out credentials \
-k $SNAPCRAFT_CREDENTIALS_KEY
- run:
name: Authenticate snapcraft
command: snapcraft login --with credentials
- run:
name: Push/release snap
command: snapcraft push *.snap --release edge
workflows:
version: 2
commit:
jobs:
- build
- release:
requires: [build]
filters:
branches:
only: master
Let’s break that down piece by piece.
defaults: &defaults
working_directory: ~/workspace
docker:
- image: snapcore/snapcraft:edge
This is a YAML anchor. It doesn’t do anything by itself, but we’ll be using it below to keep each job using the same settings. It provides a specification for the working directory (where we’ll build the snap) and tells CircleCI which Docker image to use.
version: 2
As we mentioned previously, we’re using platform v2.0. This is how we communicate that to CircleCI.
jobs:
build:
<<: *defaults
steps:
- checkout
- run:
name: Update index
command: apt update
- run:
name: Build snap
command: snapcraft
- persist_to_workspace:
root: ~/workspace
paths: ['*.snap']
Here we create the build
job, responsible for-- you guessed it-- building the snap. We use our defaults
anchor for the correct settings, and provide a number of steps to conduct the build:
- Checkout the code
- Install snapcraft
- Build the snap
- Cache the snap (so we can use it later)
release:
<<: *defaults
steps:
- checkout
- attach_workspace:
at: ~/workspace
- run:
name: Install prerequisites
command: |
sudo apt update
apt install -y openssl
- run:
name: Decrypt credentials
command: |
openssl aes-256-cbc -d \
-in .circleci/credentials.enc \
-out credentials \
-k $SNAPCRAFT_CREDENTIALS_KEY
- run:
name: Authenticate snapcraft
command: snapcraft login --with credentials
- run:
name: Push/release snap
command: snapcraft push *.snap --release edge
Here we create the release
job, responsible for pushing and releasing the snap in the store. Again, we use our defaults
anchor for the correct settings, and provide a number of steps to push/release the snap:
- Checkout the code
- Attach the workspace we cached in the
build
step (thus getting the already-built snap)
- Install openssl
- Using openssl (and the environment variable we just created containing the password), decrypt the credentials
- Using snapcraft, login with the now-decrypted credentials, and push the snap, releasing to the
edge
channel.
workflows:
version: 2
commit:
jobs:
- build
- release:
requires: [build]
filters:
branches:
only: master
The workflows
key gives us the ability to define when these jobs run. We create a single workflow named “commit” which runs on every commit (pull requests made, commits pushed to branches, etc.). That workflow consists of both of the jobs we just defined. The build
job runs on every commit (e.g. when a pull request is created, the build
job will run). However, the release
job has a filter on it that causes it to only run on the master
branch.
That’s it! To finish, commit the changes and push, using these commands:
git add .circleci/config.yml
git commit -m 'Enable continuous delivery of the snap from CircleCI'
git push
Go to back to CircleCI and select “workflows”. You’ll either see one pending, or already running. Select it, and you’ll see two jobs: the build
job and the release
job. Once the release
job finishes, you should see a final message that looks something like this:
/snap/bin/snapcraft push *.snap --release edge
Pushing hello-kyrofa_2.10_amd64.snap
After pushing, an attempt to release to ['edge'] will be made
Preparing to push '/home/circleci/workspace/hello-kyrofa_2.10_amd64.snap' to the store.
Pushing hello-kyrofa_2.10_amd64.snap [] 100%
Processing...|
Ready to release!
Revision 1 of 'hello-kyrofa' created.
Track Arch Channel Version Revision
latest amd64 stable - -
candidate - -
beta - -
edge 2.10 1
You may have also received an email message from CircleCI notifying you about the successful execution, and another from the store notifying you about the new snap.
Congratulations! Now you can spread the word and tell everybody to help you test your app by running a single command:
$ snap install hello-kyrofa --edge