Skip to content

Commit

Permalink
Migrate from Azure Pipelines to Github Actions (#474)
Browse files Browse the repository at this point in the history
This commit migrates wasmtime's CI infrastructure from Azure Pipelines
to Github Actions. Using Github Actions has a few benefits over other
offerings:

* Being natively integrated with Github means that there's no degree of
  user account configuration or access control management, it's all
  inherent via already existing Github permissions.

* Github Actions gives 20 parallel builders instead of Azure's 10 by
  default, which is a nice boost to have!

Overall I've found Github Actions to feel a bit cleaner than Azure
Pipelines as well. Subjectively I've found the configuration to be more
readable and more pleasant to work with, although they're both just as
"powerful" I think. Additionally Github Actions has been pretty solid in
my own personal testing for a number of other projects.

The main trickiness with wasmtime's CI is the rolling `dev` release of
the master branch as well as binary releases for tags. Github Actions
doesn't have quite as much built in functionality as Azure Pipelines,
but Github Actions does have a nice feature where you can define the
code for an action locally rather than only using built-in actions.

This migration adds three local actions with some associated JS code to
run the action (currently it looks like it basically requires JS)

* An `install-rust` action papers over the gotchas about installing
  Rust, allowing Rust installation to be a one-liner in the configuration.

* A `binary-compatible-builds` action allows easily configuring the
  wheels and the binaries to be "more binary compatible" and handles
  things like compilation flags on OSX and Windows while handling the
  `centos:6` container on Linux.

* The `github-release` action is the logic using the `@actions/github`
  JS package to orchestrate the custom way we manage rolling releases,
  ensuring that a new release is made for the master branch under `dev`
  (deleting the previous tag/release ahead of time) and then also
  manages tagged releases by uploading them there.

I'm hoping that most of the inline actions here will largely go away.
For example `install-rust` should be simply `rustup update $toolchain`
once various environment issues are fixed on Github Actions runner
images. Additionally `github-release` will ideally migrate to something
like https://github.com/actions/create-release or similar once it has
enough functionality. I'm also hoping that the maintenance in the
meantime of these actions is pretty low-cost, but if it becomes an issue
we can look into other solutions!
  • Loading branch information
alexcrichton authored and sunfishcode committed Nov 6, 2019
1 parent c0c7851 commit 10f2719
Show file tree
Hide file tree
Showing 18 changed files with 675 additions and 545 deletions.
257 changes: 0 additions & 257 deletions .azure-pipelines.yml

This file was deleted.

9 changes: 9 additions & 0 deletions .github/actions/binary-compatible-builds/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# binary-compatible-builds

A small (ish) action which is intended to be used and will configure builds of
Rust projects to be "more binary compatible". On Windows and macOS this
involves setting a few env vars, and on Linux this involves spinning up a CentOS
6 container which is running in the background.

All subsequent build commands need to be wrapped in `$CENTOS` to optionally run
on `$CENTOS` on Linux to ensure builds happen inside the container.
6 changes: 6 additions & 0 deletions .github/actions/binary-compatible-builds/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: 'Set up a CentOS 6 container to build releases in'
description: 'Set up a CentOS 6 container to build releases in'

runs:
using: node12
main: 'main.js'
68 changes: 68 additions & 0 deletions .github/actions/binary-compatible-builds/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env node

const child_process = require('child_process');
const stdio = { stdio: 'inherit' };

// On OSX all we need to do is configure our deployment target as old as
// possible. For now 10.9 is the limit.
if (process.platform == 'darwin') {
console.log("::set-env name=MACOSX_DEPLOYMENT_TARGET::10.9");
console.log("::set-env name=python::python3");
return;
}

// On Windows we build against the static CRT to reduce dll dependencies
if (process.platform == 'win32') {
console.log("::set-env name=RUSTFLAGS::-Ctarget-feature=+crt-static");
console.log("::set-env name=python::python");
return;
}

// ... and on Linux we do fancy things with containers. We'll spawn an old
// CentOS container in the background with a super old glibc, and then we'll run
// commands in there with the `$CENTOS` env var.

if (process.env.CENTOS !== undefined) {
const args = ['exec', '-w', process.cwd(), '-i', 'centos'];
for (const arg of process.argv.slice(2)) {
args.push(arg);
}
child_process.execFileSync('docker', args, stdio);
return;
}

// Add our rust mount onto PATH, but also add some stuff to PATH from
// the packages that we install.
let path = process.env.PATH;
path = `${path}:/rust/bin`;
path = `/opt/rh/devtoolset-8/root/usr/bin:${path}`;
path = `/opt/rh/rh-python36/root/usr/bin:${path}`;

// Spawn a container daemonized in the background which we'll connect to via
// `docker exec`. This'll have access to the current directory.
child_process.execFileSync('docker', [
'run',
'-di',
'--name', 'centos',
'-v', `${process.cwd()}:${process.cwd()}`,
'-v', `${child_process.execSync('rustc --print sysroot').toString().trim()}:/rust:ro`,
'--env', `PATH=${path}`,
'centos:6',
], stdio);

// Use ourselves to run future commands
console.log(`::set-env name=CENTOS::${__filename}`)

// See https://edwards.sdsu.edu/research/c11-on-centos-6/ for where these
const exec = s => {
child_process.execSync(`docker exec centos ${s}`, stdio);
};
exec('yum install -y centos-release-scl cmake xz epel-release');
exec('yum install -y rh-python36 patchelf unzip');
exec('yum install -y devtoolset-8-gcc devtoolset-8-binutils devtoolset-8-gcc-c++');

// Delete `libstdc++.so` to force gcc to link against `libstdc++.a` instead.
// This is a hack and not the right way to do this, but it ends up doing the
// right thing for now.
exec('rm -f /opt/rh/devtoolset-8/root/usr/lib/gcc/x86_64-redhat-linux/8/libstdc++.so');
console.log("::set-env name=python::python3");
8 changes: 8 additions & 0 deletions .github/actions/github-release/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM node:slim

COPY . /action
WORKDIR /action

RUN npm install --production

ENTRYPOINT ["node", "/action/main.js"]
18 changes: 18 additions & 0 deletions .github/actions/github-release/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# github-release

An action used to publish GitHub releases for `wasmtime`.

As of the time of this writing there's a few actions floating around which
perform github releases but they all tend to have their set of drawbacks.
Additionally nothing handles deleting releases which we need for our rolling
`dev` release.

To handle all this this action rolls-its-own implementation using the
actions/toolkit repository and packages published there. These run in a Docker
container and take various inputs to orchestrate the release from the build.

More comments can be found in `main.js`.

Testing this is really hard. If you want to try though run `npm install` and
then `node main.js`. You'll have to configure a bunch of env vars though to get
anything reasonably working.
15 changes: 15 additions & 0 deletions .github/actions/github-release/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: 'wasmtime github releases'
description: 'wasmtime github releases'
inputs:
token:
description: ''
required: true
name:
description: ''
required: true
files:
description: ''
required: true
runs:
using: 'docker'
image: 'Dockerfile'
Loading

0 comments on commit 10f2719

Please sign in to comment.