Github actions and cross-platform building

Hello, Habr. This article is about how to set up building on all platforms using github actions.







Background



I wrote a simple application on electron, I myself used linux, but my friend preferred macos. When I tried to compile for macos on my computer and handed pkg to my friend - It did not start. As a result, it turned out the only option to compile an application for macos was to compile it on macos. To simplify the task as much as possible, I made three scripts: build: linux, build: mac, build: win. As a result, after compilation, the following files were obtained: linux.deb, linux.AppImage, mac.pkg, win.exe. But there remained one problem that needed to be compiled on different systems. And then the salvation of gihub actions.







How everything should work



I press the new release button on github, and then the magic starts workflow on github actions, it compiles on all operating systems and adding binaries to the release







I used https://github.com/JasonEtco/upload-to-releas to add files to release, however there was one catch with this action. This is a container action, and in github actions, container actions are only available on linux. Therefore, it was decided to use four jobs, 3 for compilation and 1 for loading. Since the environment is not preserved for each job, this is why artifacts are used to exchange between them







Practice



First, in the .github / workflows / workflow.yml folder with the contents







name: CI on: release
      
      





Well, I think it’s clear that this is CI workflow and it will be launched on release, and now the most important job







 jobs: build-linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Install bluetooth run: sudo apt-get install -y build-essential libbluetooth-dev - name: Install dependencies run: npm install - name: Build linux run: npm run build:linux - name: Creating out run: | mkdir out cp dist/linux.AppImage out/ cp dist/linux.deb out/ - name: Upload build uses: actions/upload-artifact@master with: name: linux path: out
      
      





The steps of jobs: this is all the work, build-linux: this is the work with the name build-linux, runs-on: ubuntu-latest says that you need to run everything under the latest ubuntu







And then the most interesting steps: and all that is under it is what our work will do







Firstly - uses: ations / checkout @ v1 clones the repository so we can use it. The next step Install bluetooth installs bluetooth since the project uses it. Next, dependencies are established and a build occurs. Since after building, in the dist folder there are not only binaries, but also unnecessary garbage, so the next step is to create another folder in which only binaries are located, and then load them into artifacts.







Almost the same for win with macos







  build-mac: runs-on: macOS-latest steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: node-version: '8.x' - name: Install dependencies run: npm install - name: Build mac run: npm run build:mac - name: Creating out run: | mkdir out cp dist/mac.pkg out/ - name: Upload build uses: actions/upload-artifact@master with: name: mac path: out build-win: runs-on: windows-latest steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: node-version: '8.x' - name: Install dependencies run: npm install - name: Build win run: npm run build:win - name: Creating out run: | mkdir out copy dist\win.exe out\ - name: Upload build uses: actions/upload-artifact@master with: name: win path: out
      
      





However, it is worth noting some differences. Firstly, you do not need to install bluetooth, it is already installed, however, you need to install nodejs for this, use actions / setup-node. Also, windows uses other commands at the Creating out stage.







And of course the final stage is uploading files to the release







 upload: runs-on: ubuntu-latest needs: [build-linux, build-mac, build-win] steps: - uses: actions/checkout@v1 - name: Download linux artifact uses: actions/download-artifact@master with: name: linux - name: Download mac artifact uses: actions/download-artifact@master with: name: mac - name: Download win artifact uses: actions/download-artifact@master with: name: win - name: Upload to Release deb uses: JasonEtco/upload-to-release@v0.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: linux/linux.deb application/vnd.debian.binary-package - name: Upload to Release AppImage uses: JasonEtco/upload-to-release@v0.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: linux/linux.AppImage application/x-executable - name: Upload to Release pkg uses: JasonEtco/upload-to-release@v0.31.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: mac/mac.pkg application/x-xar - name: Upload to Release exe uses: JasonEtco/upload-to-release@v0.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: args: win/win.exe application/octet-stream
      
      





The very important part is that needs, this line says that you need to start work only after all the builds (if the builds go in parallel), then first we download the artifacts, and then add the binaries from them to the release







References



Resulting workflow.yml file







Repository







More about github actions







Thanks for your attention!








All Articles