CI: build: add option to disable use of ccache
[openwrt/openwrt.git] / .github / workflows / build.yml
index ef7fc51d9ad67e5c67bb8566999bd594ae3723f3..27ed5cc218e370e54a14488161a173e1f971d2f9 100644 (file)
@@ -54,6 +54,9 @@ on:
         type: boolean
       upload_external_toolchain:
         type: boolean
+      use_ccache_cache:
+        type: boolean
+        default: true
 
 permissions:
   contents: read
@@ -64,8 +67,8 @@ jobs:
     runs-on: ubuntu-latest
     outputs:
       owner_lc: ${{ steps.lower_owner.outputs.owner_lc }}
-      ccache_hash: ${{ steps.ccache_hash.outputs.ccache_hash }}
       container_tag: ${{ steps.determine_tools_container.outputs.container_tag }}
+      container_name: ${{ steps.determine_tools_container.outputs.container_name }}
 
     steps:
       - name: Checkout
@@ -83,13 +86,6 @@ jobs:
 
           echo "owner_lc=$OWNER_LC" >> $GITHUB_OUTPUT
 
-      - name: Generate ccache hash
-        id: ccache_hash
-        run: |
-          CCACHE_HASH=$(md5sum include/kernel-* | awk '{ print $1 }' \
-           | md5sum | awk '{ print $1 }')
-          echo "ccache_hash=$CCACHE_HASH" >> $GITHUB_OUTPUT
-
       # Per branch tools container tag
       # By default stick to latest
       # For official test targetting openwrt stable branch
@@ -99,6 +95,7 @@ jobs:
       - name: Determine tools container tag
         id: determine_tools_container
         run: |
+          CONTAINER_NAME=${{ inputs.container_name }}
           CONTAINER_TAG=latest
           if [ -n "${{ github.base_ref }}" ]; then
             if echo "${{ github.base_ref }}" | grep -q -E '^openwrt-[0-9][0-9]\.[0-9][0-9]$'; then
@@ -115,19 +112,34 @@ jobs:
               CONTAINER_TAG=openwrt-"$(echo ${{ github.ref_name }} | sed 's/^v\([0-9][0-9]\.[0-9][0-9]\)\..\+/\1/')"
             fi
           fi
-          echo "Tools container to use tools:$CONTAINER_TAG"
+
+          if [ "$CONTAINER_NAME" = "toolchain" ]; then
+            GHCR_TOKEN=$(echo ${{ secrets.GITHUB_TOKEN }} | base64)
+            GHCR_HEADER="Authorization: Bearer ${GHCR_TOKEN}"
+            GHCR_MANIFEST_LINK=https://ghcr.io/v2/${{ steps.lower_owner.outputs.owner_lc }}/${{ inputs.container_name }}/manifests/${{ inputs.target }}-${{ inputs.subtarget }}-"$CONTAINER_TAG"
+            # Check if container exist
+            if [ $(curl -s -o /dev/null -w "%{http_code}" -H "$GHCR_HEADER" -I "$GHCR_MANIFEST_LINK") = 200 ]; then
+              CONTAINER_TAG=${{ inputs.target }}-${{ inputs.subtarget }}-"$CONTAINER_TAG"
+            else
+              CONTAINER_NAME=tools
+            fi
+          fi
+
+          echo "Tools container to use $CONTAINER_NAME:$CONTAINER_TAG"
           echo "container_tag=$CONTAINER_TAG" >> $GITHUB_OUTPUT
+          echo "container_name=$CONTAINER_NAME" >> $GITHUB_OUTPUT
 
   build:
     name: Build ${{ inputs.target }}/${{ inputs.subtarget }}
     needs: setup_build
     runs-on: ubuntu-latest
 
-    container: ghcr.io/${{ needs.setup_build.outputs.owner_lc }}/${{ inputs.container_name }}:${{ needs.setup_build.outputs.container_tag }}
+    container: ghcr.io/${{ needs.setup_build.outputs.owner_lc }}/${{ needs.setup_build.outputs.container_name }}:${{ needs.setup_build.outputs.container_tag }}
 
     permissions:
       contents: read
       packages: read
+      actions: write
 
     steps:
       - name: Checkout master directory
@@ -163,33 +175,16 @@ jobs:
           repository: openwrt/telephony
           path: openwrt/feeds/telephony
 
-      - name: Fix permission
-        run: |
-          chown -R buildbot:buildbot openwrt
-
-      - name: Prepare prebuilt tools
-        shell: su buildbot -c "sh -e {0}"
-        working-directory: openwrt
-        run: |
-          mkdir -p staging_dir build_dir
-          ln -s /prebuilt_tools/staging_dir/host staging_dir/host
-          ln -s /prebuilt_tools/build_dir/host build_dir/host
-
-          ./scripts/ext-tools.sh --refresh
-
-      - name: Update & Install feeds
-        if: inputs.include_feeds == true
-        shell: su buildbot -c "sh -e {0}"
-        working-directory: openwrt
-        run: |
-          ./scripts/feeds update -a
-          ./scripts/feeds install -a
-
       - name: Parse toolchain file
         if: inputs.build_toolchain == false
         id: parse-toolchain
         working-directory: openwrt
         run: |
+          if [ -d /external-toolchain/ ]; then
+            echo "toolchain-type=external_container" >> $GITHUB_OUTPUT
+            exit 0
+          fi
+
           TOOLCHAIN_PATH=snapshots
 
           if [ -n "${{ github.base_ref }}" ]; then
@@ -234,16 +229,40 @@ jobs:
           echo "TOOLCHAIN_FILE=$TOOLCHAIN_FILE" >> "$GITHUB_ENV"
           echo "TOOLCHAIN_PATH=$TOOLCHAIN_PATH" >> "$GITHUB_ENV"
 
-      - name: Cache ccache
-        uses: actions/cache@v3
+      - name: Fix permission
+        run: |
+          chown -R buildbot:buildbot openwrt
+
+      - name: Prepare prebuilt tools
+        shell: su buildbot -c "sh -e {0}"
+        working-directory: openwrt
+        run: |
+          mkdir -p staging_dir build_dir
+          ln -s /prebuilt_tools/staging_dir/host staging_dir/host
+          ln -s /prebuilt_tools/build_dir/host build_dir/host
+
+          ./scripts/ext-tools.sh --refresh
+
+      - name: Update & Install feeds
+        if: inputs.include_feeds == true
+        shell: su buildbot -c "sh -e {0}"
+        working-directory: openwrt
+        run: |
+          ./scripts/feeds update -a
+          ./scripts/feeds install -a
+
+      - name: Restore ccache cache
+        id: restore-ccache-cache
+        if: inputs.use_ccache_cache == true
+        uses: actions/cache/restore@v3
         with:
           path: openwrt/.ccache
-          key: ccache-kernel-${{ inputs.target }}/${{ inputs.subtarget }}-${{ needs.setup_build.outputs.ccache_hash }}
+          key: ccache-kernel-${{ inputs.target }}/${{ inputs.subtarget }}-${{ hashFiles('openwrt/include/kernel-**') }}
           restore-keys: |
             ccache-kernel-${{ inputs.target }}/${{ inputs.subtarget }}-
 
       - name: Download external toolchain/sdk
-        if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type != 'internal'
+        if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type != 'internal' && steps.parse-toolchain.outputs.toolchain-type != 'external_container'
         shell: su buildbot -c "sh -e {0}"
         working-directory: openwrt
         run: |
@@ -280,6 +299,26 @@ jobs:
           echo CONFIG_TARGET_PER_DEVICE_ROOTFS=y >> .config
           echo CONFIG_TARGET_ALL_PROFILES=y >> .config
 
+      - name: Configure ccache
+        if: inputs.use_ccache_cache == true
+        shell: su buildbot -c "sh -e {0}"
+        working-directory: openwrt
+        run: |
+          echo CONFIG_CCACHE=y >> .config
+
+      - name: Configure external toolchain in container
+        if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type == 'external_container'
+        shell: su buildbot -c "sh -e {0}"
+        working-directory: openwrt
+        run: |
+          echo CONFIG_DEVEL=y >> .config
+          echo CONFIG_AUTOREMOVE=y >> .config
+
+          ./scripts/ext-toolchain.sh \
+            --toolchain /external-toolchain/$(ls /external-toolchain/ | grep openwrt-toolchain)/toolchain-* \
+            --overwrite-config \
+            --config ${{ inputs.target }}/${{ inputs.subtarget }}
+
       - name: Configure external toolchain
         if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type == 'external_toolchain'
         shell: su buildbot -c "sh -e {0}"
@@ -287,7 +326,6 @@ jobs:
         run: |
           echo CONFIG_DEVEL=y >> .config
           echo CONFIG_AUTOREMOVE=y >> .config
-          echo CONFIG_CCACHE=y >> .config
 
           ./scripts/ext-toolchain.sh \
             --toolchain ${{ env.TOOLCHAIN_FILE }}/toolchain-* \
@@ -329,7 +367,6 @@ jobs:
         run: |
           echo CONFIG_DEVEL=y >> .config
           echo CONFIG_AUTOREMOVE=y >> .config
-          echo CONFIG_CCACHE=y >> .config
 
           ./scripts/ext-toolchain.sh \
             --toolchain ${{ env.TOOLCHAIN_FILE }}/staging_dir/toolchain-* \
@@ -343,7 +380,6 @@ jobs:
         run: |
           echo CONFIG_DEVEL=y >> .config
           echo CONFIG_AUTOREMOVE=y >> .config
-          echo CONFIG_CCACHE=y >> .config
 
           echo "CONFIG_TARGET_${{ inputs.target }}=y" >> .config
           echo "CONFIG_TARGET_${{ inputs.target }}_${{ inputs.subtarget }}=y" >> .config
@@ -447,6 +483,23 @@ jobs:
           name: ${{ inputs.target }}-${{ inputs.subtarget }}-logs
           path: "openwrt/logs"
 
+      - name: Delete already present ccache cache
+        if: steps.restore-ccache-cache.outputs.cache-hit == 'true' && inputs.use_ccache_cache == true
+        uses: octokit/request-action@v2.x
+        with:
+          route: DELETE /repos/{repository}/actions/caches?key={key}
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          INPUT_REPOSITORY: ${{ github.repository }}
+          INPUT_KEY: ${{ steps.restore-ccache-cache.outputs.cache-primary-key }}
+
+      - name: Save ccache cache
+        if: inputs.use_ccache_cache == true
+        uses: actions/cache/save@v3
+        with:
+          path: openwrt/.ccache
+          key: ${{ steps.restore-ccache-cache.outputs.cache-primary-key }}
+
       - name: Find external toolchain name
         id: get-toolchain-name
         if: inputs.upload_external_toolchain == true