Notes

Friday, April 22, 2022

How to use the Bond compiler (gbc) in Azure Pipelines with Ubuntu build agents

1. Create a Dockerfile to build Bond

# Use the same version of Ubuntu as the build agent.
FROM ubuntu:20.04 as gbc

# Prevent tzdata from hanging the build
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
    && apt-get install -y \
        curl \
        git \
        clang \
        cmake \
        zlib1g-dev \
        libboost-dev \
        libboost-thread-dev

# Use clang instead of gcc
RUN update-alternatives --set cc /usr/bin/clang

# Install the Haskell Tool Stack
RUN curl -sSL https://get.haskellstack.org/ | sh

RUN git clone --recursive https://github.com/microsoft/bond.git

WORKDIR /bond/build
RUN git checkout tags/10.0.0
RUN cmake -DBOND_ENABLE_GRPC=FALSE .. && make && make install

2. Run the build

PS> docker build -t bond -f .\Dockerfile .

The build takes about 10 minutes. After the build (hopefully) succeeds, extract the gbc executable.

PS> docker create --name bond bond
PS> mkdir bond
PS> docker cp bond:/bond/build/compiler/build/gbc/gbc ./bond/gbc
PS> docker rm bond

3. Upload gbc to Azure Artifacts with Azure CLI

PS> az artifacts universal publish `
    --organization <organisation> 
    --scope project --project <project> `
    --feed <feed> `
    --name bond --version 10.0.0 `
    --description "gbc, the Bond compiler/codegen tool" `
    --path ./bond

4. Download and use gbc in Azure Pipelines

- task: UniversalPackages@0
    displayName: 'Download Bond compiler'
    inputs:
        command: download
        vstsFeed: '<project>/<feed>'
        vstsFeedPackage: 'bond'
        vstsPackageVersion: '10.0.0'
        downloadDirectory: '$(Build.SourcesDirectory)/bond'

- task: CmdLine@2
    displayName: 'Update file permissions on Bond compiler'
    inputs:
        script: 'chmod +x $(Build.SourcesDirectory)/bond/gbc'

- task: DotNetCoreCLI@2
    displayName: Build
    inputs:
        command: build
        arguments: '-p:BOND_COMPILER_PATH=$(Build.SourcesDirectory)/bond'

5. Download and use gbc in Alpine-based Docker image

I also neeed to build an Alpine based .NET app Docker image. Just showing the bits required to run gbc:

FROM mcr.microsoft.com/azure-cli:2.9.1 as cli

# Download the Universal Package with the Bond compiler
ARG AZURE_DEVOPS_EXT_PAT

WORKDIR /bond

RUN az extension add --name azure-devops \
  && az artifacts universal download \
  --organization <organization> \
  --feed <feed> \
  --scope project --project <project> \
  --name bond --version 10.0.0 --path . \
  && chmod +x ./gbc

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS publish
# gcompat and gmp are required for the Bond compiler (gbc).
RUN apk add --no-cache gcompat gmp

WORKDIR /repo
COPY . .
COPY --from=cli /bond ./bond

WORKDIR /repo/src

RUN dotnet publish -c Release -o /app/publish \
  -p:BOND_COMPILER_PATH=/repo/bond