Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish Docker image on GitHub Actions #14

Merged
merged 26 commits into from
Oct 3, 2024
Merged

Publish Docker image on GitHub Actions #14

merged 26 commits into from
Oct 3, 2024

Conversation

tombruijn
Copy link
Member

@tombruijn tombruijn commented Oct 2, 2024

Remove .sh file extension from scripts

It's not necessary to have them and we don't use the file extension in other places.

Remove ability to publish from local machines

We don't want to publish from local machines for security reasons, so remove the scripts to do it locally.

Add workflow to publish from GitHub Actions

Add a workflow that is triggered by a workflow_dispatch event, which can be triggered from the GitHub Actions UI on the repository.

Check out the repository on GitHub Actions

Build and publish the repository from GitHub Actions. For that we first need to check it out.

Check out Mono for publishing on GitHub Actions

We use Mono to handle versioning for us for our projects. Clone it on this workflow so we can create a version using changesets.

Create a new release with Mono

Call mono from the cloned location to create a new version.

It will create a version number based on the changesets and write it to the Cargo.toml using the script/write_version script.

I've supplied it with the --no-git and --no-package-push flags to make sure it will not make a Git commit and tag for this release. We will do that manually later.

The --yes flag will auto accept any interactive prompts so that it will not hang in this workflow.

Commit and tag the new release

After Mono has created a new version number and updated the changelog, commit the changes and tag the commit for the new version.

Fetch the generated version number using GitHub Actions 'outputs' rather than running script/read_version all the time so it's easy to reference in later steps in the workflow.

Login to Docker in publish workflow

Before we can push new images to Docker Hub, login first using our publish user.

Set up Docker buildx in the workflow

Before we can build and ship the project's Docker image, set up the buildx environment.

Build and push the Docker image to Docker Hub

Build the image using Docker builx, tag the images built and push them to Docker Hub.

Push the release commit and tag to the repository

After the new images have been pushed, push the release commit and tag to the repository. The commit will be pushed to the branch the workflow was triggered from.

Check out the repository using a deploy key

When we check out the repository using a deploy key. This will work around a GitHub Actions limitation. When we push a commit, it will trigger the GitHub Actions CI to run. Without using a deploy key, the CI workflow will not trigger.

Configure Git for making commits

We need to author the commits as someone for making commits. Use the release bot user for this purpose.

Disable mono build in publish workflow

The build step is run before the publish step. That won't work in the GitHub Actions workflow, so disable mono build.

Exit version scripts on the first error

By default bash scripts don't exit when a command has a failure exit status.

Configure it with set -eu to exit on command failures and undefined variables.

Rewrite write_version to Ruby

The sed script doesn't work on GitHub Actions, so use Ruby instead.

Add Rake task to install cross

I'm moving the build steps to a Rakefile, because the code to cross compile and build the release image gets more complex than I'm comfortable in maintaining a Makefile.

The first step is to install cross and ensure it's always using the same version.

I've copied the command runner from our agent project and updated it a bit.

Add buildx setup task

Move the buildx setup task to a Rake task instead of a make command as part of the process to move this to Rake tasks.

Configure cross to use our build images

Ensure we have full control of the build environment by using our own private build images.

Add project build tasks

These tasks will build the release artifacts that will be copied to the release image. They have to be built separately because the emulation on GitHub Actions runners is so slow it takes 55 minutes to build the ARM target.

This follows the setup we have in our agent project. It first builds the release artifacts separately and then copies them onto the Docker image. That last step will be done in a future commit.

https://appsignal.slack.com/archives/C06R4337AJ1/p1727689745049589

Clean up release directory between builds

Ensure we don't accidentally reuse an older release artifact by clearing the release directory before every build.

Build the release image locally

Rewrite the make command to a Rake task to test the release image locally.

Instead of making the Docker image with a two stage build step, copy the release artifact onto the image. This significantly reduces the build time, as building this image for the ARM platform takes 55 minutes on GitHub Actions.

I've given the locally built image the tag 'local' so that it doesn't overwite any pulled release images to avoid confusion about what image tag someeone is running.

Add publish Rake task

Rewrite the make command to a Rake task to publish the release image.

Add task to remove the buildx container

Make it easier to start over and reset the buildx container with this task.

Sign release Git commit to verify commits

We author the release commit as the AppSignal release bot. Add their signing key to the workflow so that the release commit that is pushed is verified.

Sync Rake task output

On GitHub Actions the Rake task output isn't printed immediately but buffered until the processed exists. Add this line to output the puts statements immediately.

[skip changeset]

It's not necessary to have them and we don't use the file extension
in other places.
We don't want to publish from local machines for security reasons, so
remove the scripts to do it locally.
Add a workflow that is triggered by a `workflow_dispatch` event, which
can be triggered from the GitHub Actions UI on the repository.
Build and publish the repository from GitHub Actions. For that we first
need to check it out.
We use Mono to handle versioning for us for our projects. Clone it on
this workflow so we can create a version using changesets.
Call mono from the cloned location to create a new version.

It will create a version number based on the changesets and write it to
the `Cargo.toml` using the `script/write_version` script.

I've supplied it with the `--no-git` and `--no-package-push` flags
to make sure it will not make a Git commit and tag for this release. We
will do that manually later.

The `--yes` flag will auto accept any interactive prompts so that it
will not hang in this workflow.
After Mono has created a new version number and updated the changelog,
commit the changes and tag the commit for the new version.

Fetch the generated version number using GitHub Actions 'outputs' rather
than running `script/read_version` all the time so it's easy to
reference in later steps in the workflow.
Before we can push new images to Docker Hub, login first using our
publish user.
Before we can build and ship the project's Docker image, set up the
buildx environment.
Build the image using Docker builx, tag the images built and push them
to Docker Hub.
After the new images have been pushed, push the release commit and tag
to the repository. The commit will be pushed to the branch the workflow
was triggered from.
When we check out the repository using a deploy key. This will work
around a GitHub Actions limitation. When we push a commit, it will
trigger the GitHub Actions CI to run. Without using a deploy key, the CI
workflow will not trigger.
We need to author the commits as someone for making commits.
Use the release bot user for this purpose.
The build step is run before the publish step. That won't work in the
GitHub Actions workflow, so disable `mono build`.
By default bash scripts don't exit when a command has a failure exit
status.

Configure it with `set -eu` to exit on command failures and undefined
variables.
The sed script doesn't work on GitHub Actions, so use Ruby instead.
I'm moving the build steps to a Rakefile, because the code to cross
compile and build the release image gets more complex than I'm
comfortable in maintaining a Makefile.

The first step is to install cross and ensure it's always using
the same version.

I've copied the command runner from our agent project and updated it
a bit.
Move the buildx setup task to a Rake task instead of a make command
as part of the process to move this to Rake tasks.
Ensure we have full control of the build environment by using our
own private build images.
These tasks will build the release artifacts that will be copied
to the release image. They have to be built separately because
the emulation on GitHub Actions runners is so slow it takes 55
minutes to build the ARM target.

This follows the setup we have in our agent project. It first builds the
release artifacts separately and then copies them onto the Docker image.
That last step will be done in a future commit.

https://appsignal.slack.com/archives/C06R4337AJ1/p1727689745049589
Ensure we don't accidentally reuse an older release artifact
by clearing the release directory before every build.
Rewrite the make command to a Rake task to test the release image
locally.

Instead of making the Docker image with a two stage build step, copy the
release artifact onto the image. This significantly reduces the build
time, as building this image for the ARM platform takes 55 minutes on
GitHub Actions.

I've given the locally built image the tag 'local' so that it doesn't
overwite any pulled release images to avoid confusion about what image
tag someeone is running.
@tombruijn tombruijn self-assigned this Oct 2, 2024
Rewrite the make command to a Rake task to publish the release image.
Make it easier to start over and reset the buildx container with this
task.
We author the release commit as the AppSignal release bot. Add their
signing key to the workflow so that the release commit that is pushed is
verified.
On GitHub Actions the Rake task output isn't printed immediately but
buffered until the processed exists. Add this line to output the puts
statements immediately.
@tombruijn tombruijn marked this pull request as ready for review October 2, 2024 16:23
@tombruijn tombruijn merged commit 7122b59 into main Oct 3, 2024
1 check passed
@tombruijn tombruijn deleted the publish-on-ci branch October 3, 2024 13:36
unflxw added a commit that referenced this pull request Oct 14, 2024
Leftover from #14.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants