name: Vib Build on: push: branches: [ "main" ] tags: - '*' schedule: - cron: '21 */6 * * *' pull_request: workflow_dispatch: env: CUSTOM_IMAGE_NAME: custom BUILDX_NO_DEFAULT_ATTESTATIONS: 1 jobs: verify_image: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get install -y libfyaml-utils - name: Read base image name from recipe id: read_base_recipe run: | BASE_IMAGE="$(fy-filter -f recipe.yml /stages/-1/base)" echo The base image is $BASE_IMAGE if [ -z $BASE_IMAGE ]; then exit 1; fi echo "base_image=$BASE_IMAGE" >> "$GITHUB_OUTPUT" echo "BASE_IMAGE=$BASE_IMAGE" >> "$GITHUB_ENV" - name: Verify Base Image Integrity run: | gh attestation verify oci://ghcr.io/${{ env.BASE_IMAGE }} --owner Vanilla-OS env: GH_TOKEN: ${{ github.token }} check_update: runs-on: ubuntu-latest outputs: has_updates: ${{ steps.set_output.outputs.has_updates }} base_image: ${{ steps.read_base_recipe.outputs.base_image }} permissions: contents: write # Allow actions to create a digest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies run: sudo apt-get install -y jq skopeo libfyaml-utils - name: Read base image name from recipe id: read_base_recipe run: | BASE_IMAGE="$(fy-filter -f recipe.yml /stages/-1/base)" echo The base image is $BASE_IMAGE if [ -z $BASE_IMAGE ]; then exit 1; fi echo "base_image=$BASE_IMAGE" >> "$GITHUB_OUTPUT" echo "BASE_IMAGE=$BASE_IMAGE" >> "$GITHUB_ENV" - name: Get last successful run if: ${{ github.ref_type == 'branch' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} continue-on-error: true run: | gh run list -b "${{ github.ref_name }}" -w "${{ github.workflow }}" -s "success" -L 1 --json databaseId > last_run.json echo "LAST_RUN_ID=$(jq -r '.[0].databaseId' last_run.json)" >> "$GITHUB_ENV" - name: Download the previous digest uses: actions/download-artifact@v4 continue-on-error: true with: name: digest github-token: ${{ github.token }} run-id: ${{ env.LAST_RUN_ID }} - name: Check if there was an update to the base image run: | touch digest.txt mv digest.txt last_digest.txt skopeo inspect --raw docker://${{ env.BASE_IMAGE }} | sha256sum > digest.txt echo Old digest is: $(cat last_digest.txt) echo New digest is: $(cat digest.txt) echo "HAS_UPDATES=$(cmp -s digest.txt last_digest.txt; echo $?)" >> "$GITHUB_ENV" - name: Upload current digest uses: actions/upload-artifact@v4 with: name: digest path: digest.txt - name: Set output id: set_output run: | if [ ${{ github.event_name == 'schedule'}} == false ] then echo action was manually run, updating either way echo "has_updates=true" >> "$GITHUB_OUTPUT" elif [ ${{ env.HAS_UPDATES }} == 1 ] then echo base image was updated since the last build echo "has_updates=true" >> "$GITHUB_OUTPUT" else echo no updates to the base image since the last build echo "has_updates=false" >> "$GITHUB_OUTPUT" fi build: runs-on: ubuntu-latest needs: [check_update, verify_image] if: ${{ needs.check_update.outputs.has_updates == 'true' }} permissions: packages: write # Allow pushing images to GHCR attestations: write # To create and write attestations id-token: write # Additional permissions for the persistence of the attestations steps: - uses: actions/checkout@v4 - uses: vanilla-os/vib-gh-action@v0.8.1 with: recipe: 'recipe.yml' plugins: 'Vanilla-OS/vib-fsguard:v1.5.3' - uses: actions/upload-artifact@v4 with: name: Containerfile path: Containerfile - name: Generate image name run: | REPO_OWNER_LOWERCASE="$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" echo "REPO_OWNER_LOWERCASE=$REPO_OWNER_LOWERCASE">> "$GITHUB_ENV" echo "IMAGE_URL=ghcr.io/$REPO_OWNER_LOWERCASE/${{ env.CUSTOM_IMAGE_NAME }}">> "$GITHUB_ENV" - name: Set image info run: | echo -n "${{ needs.check_update.outputs.base_image }}" > ./includes.container/image-info/base-image-name echo -n "${{ env.REPO_OWNER_LOWERCASE }}/${{ env.CUSTOM_IMAGE_NAME }}" > ./includes.container/image-info/image-name - name: Docker meta id: docker_meta uses: docker/metadata-action@v5 with: images: | ${{ env. IMAGE_URL }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{raw}} type=semver,pattern=v{{major}} type=ref,event=branch - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GitHub Package Registry uses: docker/login-action@v3 if: ${{ github.event_name != 'pull_request' }} with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and Push the Docker image id: push uses: docker/build-push-action@v6 with: context: . file: Containerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.docker_meta.outputs.tags }} labels: ${{ steps.docker_meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max platforms: linux/amd64 provenance: false - name: Attest pushed image uses: actions/attest-build-provenance@v1 id: attest if: ${{ github.event_name != 'pull_request' }} with: subject-name: ${{ env.IMAGE_URL }} subject-digest: ${{ steps.push.outputs.digest }} push-to-registry: false