Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .github/workflows/build-ci-container-code-format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: Build CI Container

permissions:
contents: read

on:
push:
branches:
- main
paths:
- .github/workflows/build-ci-container-code-format.yml
- '.github/workflows/containers/github-action-ci-code-format/**'
- llvm/utils/git/code-format-helper.py
- llvm/utils/git/requirements_formatting.txt
- llvm/utils/git/requirements_formatting.txt.in
pull_request:
paths:
- .github/workflows/build-ci-container-code-format.yml
- '.github/workflows/containers/github-action-ci-code-format/**'
- llvm/utils/git/code-format-helper.py
- llvm/utils/git/requirements_formatting.txt
- llvm/utils/git/requirements_formatting.txt.in

jobs:
build-ci-container-code-format:
if: github.repository_owner == 'llvm'
runs-on: depot-ubuntu-24.04-16
steps:
- name: Checkout LLVM
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
sparse-checkout: |
.github/workflows/containers/github-action-ci-code-format/
llvm/utils/git/requirements_formatting.txt

- name: Write Variables
id: vars
run: |
tag=$(git rev-parse --short=12 HEAD)
container_name="ghcr.io/$GITHUB_REPOSITORY_OWNER/amd64/ci-ubuntu-24.04-code-format"
echo "container-name=$container_name" >> $GITHUB_OUTPUT
echo "container-name-tag=$container_name:$tag" >> $GITHUB_OUTPUT
echo "container-filename=$(echo $container_name:$tag | sed -e 's/\//-/g' -e 's/:/-/g').tar" >> $GITHUB_OUTPUT
- name: Build container
run: |
podman build --target ci-container-code-format \
-f .github/workflows/containers/github-action-ci-code-format/Dockerfile \
-t ${{ steps.vars.outputs.container-name-tag }} .

# Save the container so we have it in case the push fails. This also
# allows us to separate the push step into a different job so we can
# maintain minimal permissions while building the container.
- name: Save container image
run: |
podman save ${{ steps.vars.outputs.container-name-tag }} > ${{ steps.vars.outputs.container-filename }}

- name: Upload container image
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: container-amd64
path: "*.tar"
retention-days: 14

- name: Test Container
run: |
for image in ${{ steps.vars.outputs.container-name-tag }}; do
# Use --pull=never to ensure we are testing the just built image.
podman run --pull=never --rm -it $image /usr/bin/bash -x -c 'cd $HOME && clang-format --version | grep version'
done

push-ci-container:
if: github.event_name == 'push'
needs:
- build-ci-container-code-format
permissions:
packages: write
runs-on: ubuntu-24.04
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Download container
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0

- name: Push Container
run: |
function push_container {
image_name=$1
latest_name=$(echo $image_name | sed 's/:[a-f0-9]\+$/:latest/g')
podman tag $image_name $latest_name
echo "Pushing $image_name ..."
podman push $image_name
echo "Pushing $latest_name ..."
podman push $latest_name
}

podman login -u ${{ github.actor }} -p $GITHUB_TOKEN ghcr.io
for f in $(find . -iname *.tar); do
image_name=$(podman load -q -i $f | sed 's/Loaded image: //g')
push_container $image_name

if echo $image_name | grep '/amd64/'; then
# For amd64, create an alias with the arch component removed.
# This matches the convention used on dockerhub.
default_image_name=$(echo $(dirname $(dirname $image_name))/$(basename $image_name))
podman tag $image_name $default_image_name
push_container $default_image_name
fi
done
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
FROM docker.io/library/ubuntu:24.04 AS base
ENV LLVM_SYSROOT=/opt/llvm

FROM base AS clang-format-toolchain
ENV LLVM_VERSION=21.1.1

RUN apt-get update && \
apt-get install -y \
wget \
gcc \
g++ \
cmake \
ninja-build \
python3 \
git \
curl \
zlib1g-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

RUN curl -O -L https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-$LLVM_VERSION.tar.gz && \
tar -xf llvmorg-$LLVM_VERSION.tar.gz && \
rm -f llvmorg-$LLVM_VERSION.tar.gz

WORKDIR /llvm-project-llvmorg-$LLVM_VERSION

RUN cmake -B ./build -G Ninja ./llvm \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$LLVM_SYSROOT" \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_DISTRIBUTION_COMPONENTS="clang-format"

RUN ninja -C ./build install-distribution

FROM base AS ci-container-code-format

COPY --from=clang-format-toolchain $LLVM_SYSROOT $LLVM_SYSROOT

# Need nodejs for some of the GitHub actions.
# Need git for git-clang-format.
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
nodejs \
sudo \
# These are needed by the premerge pipeline. Pip and venv are used to
# install dependent python packages.
# Having a symlink from python to python3 enables code sharing between
# the Linux and Windows pipelines.
python3-pip \
python3-venv \
python-is-python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

ENV LLVM_SYSROOT=$LLVM_SYSROOT
ENV PATH=${LLVM_SYSROOT}/bin:${PATH}

# Create a new user to avoid test failures related to a lack of expected
# permissions issues in some tests. Set the user id to 1001 as that is the
# user id that Github Actions uses to perform the checkout action.
RUN useradd gha -u 1001 -m -s /bin/bash

# Also add the user to passwordless sudoers so that we can install software
# later on without having to rebuild the container.
RUN adduser gha sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER gha
WORKDIR /home/gha

# Install dependencies for 'pr-code-format.yml' job
COPY llvm/utils/git/requirements_formatting.txt /home/gha/requirements_formatting.txt
RUN python -m venv venv && \
venv/bin/pip install -r /home/gha/requirements_formatting.txt && \
rm /home/gha/requirements_formatting.txt
Loading