diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 0000000000000..1aaa1553143de --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,80 @@ +name: 🏗️ Build new release + +on: + workflow_call: + inputs: + snapd_tags: + required: true + type: string + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + snapd_tag: ${{ fromJson(inputs.snapd_tags) }} + arch: + - x86_64 + - arm64 + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -yqq \ + build-essential \ + bison \ + dwarves \ + flex \ + libelf-dev \ + gcc-aarch64-linux-gnu + - name: Configrue build variables + id: build_variables + run: | + case "${{ matrix.arch }}" in + arm64) + ARCH=arm64 + CROSS_COMPILE=aarch64-linux-gnu- + IMAGE_NAME=Image.gz + ;; + x86|x86_64) + ARCH=x86 + CROSS_COMPILE= + IMAGE_NAME=bzImage + ;; + *) + false + ;; + esac + + echo "::echo::on" + echo "::set-output name=architecture::$ARCH" + echo "::set-output name=build_output_filename::arch/$ARCH/boot/$IMAGE_NAME" + echo "::set-output name=cross_compile::$CROSS_COMPILE" + echo "::set-output name=release_asset_filename::vmlinux-wsl2-snapd-${{ matrix.arch }}" + - uses: actions/checkout@v3 + with: + ref: ${{ matrix.snapd_tag }} + - name: Build ${{ matrix.snapd_tag }}:${{ matrix.arch }} + id: build + env: + ARCH: ${{ steps.build_variables.outputs.architecture }} + BUILD_OUTPUT_FILENAME: ${{ steps.build_variables.outputs.build_output_filename }} + CROSS_COMPILE: ${{ steps.build_variables.outputs.cross_compile }} + IMAGE_NAME: ${{ steps.build_variables.outputs.image_name }} + RELEASE_ASSET_FILENAME: ${{ steps.build_variables.outputs.release_asset_filename }} + run: | + # Verify that the WSL configuration is present + [ -f "arch/$ARCH/configs/wsl2_defconfig" ] + + make ARCH="$ARCH" wsl2_defconfig snap_support.config + make -j$(nproc) ARCH="$ARCH" ${CROSS_COMPILE:+CROSS_COMPILE=$CROSS_COMPILE} + + cp -f "$BUILD_OUTPUT_FILENAME" "$RELEASE_ASSET_FILENAME" + - name: Upload ${{ matrix.snapd_tag }}:${{ matrix.arch }} + uses: softprops/action-gh-release@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + draft: true + name: Release ${{ matrix.snapd_tag }} + tag_name: ${{ matrix.snapd_tag }} + files: ${{ steps.build_variables.outputs.release_asset_filename }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000000..a7a72310bca54 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,40 @@ +name: ⚙️ Continuous Delivery + +on: + schedule: + - cron: "0 * * * *" + workflow_dispatch: + +jobs: + trigger-sync: + if: ${{ github.repository == 'diddlesnaps/WSL2-Linux-Kernel' }} + uses: ./.github/workflows/sync-upstream.yml + secrets: inherit + + trigger-tagger: + needs: trigger-sync + if: ${{ needs.trigger-sync.outputs.missing_tags }} + uses: ./.github/workflows/tag-release.yml + secrets: inherit + with: + missing_tags: ${{ needs.trigger-sync.outputs.missing_tags }} + + trigger-build: + needs: + - trigger-sync # need to expliticly add this to access the outputs + - trigger-tagger + if: ${{ needs.trigger-sync.outputs.snapd_tags }} + uses: ./.github/workflows/build-release.yml + secrets: inherit + with: + snapd_tags: ${{ needs.trigger-sync.outputs.snapd_tags }} + + trigger-publish: + needs: + - trigger-sync # need to expliticly add this to access the outputs + - trigger-build + if: ${{ always() && needs.trigger-sync.outputs.snapd_tags }} + uses: ./.github/workflows/publish-release.yml + secrets: inherit + with: + snapd_tags: ${{ needs.trigger-sync.outputs.snapd_tags }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000000000..450d4995639cd --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,33 @@ +name: 🚀 Publish release + +on: + workflow_call: + inputs: + snapd_tags: + required: true + type: string + +jobs: + publish_or_cleanup: + runs-on: ubuntu-latest + strategy: + matrix: + snapd_tag: ${{ fromJson(inputs.snapd_tags) }} + steps: + - uses: actions/checkout@v3 + - name: Publish release ${{ matrix.snapd_tag }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + [ "$(gh release view "${{ matrix.snapd_tag }}" --repo "${{ github.repository }}" --json assets --template '{{len .assets}}')" -gt 0 ] + gh release edit "${{ matrix.snapd_tag }}" --repo "${{ github.repository }}" --draft=false + - name: Remove failed release ${{ matrix.snapd_tag }} + if: ${{ failure() || cancelled() }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SNAPD_TAG: ${{ matrix.snapd_tag }} + run: | + UPSTREAM_TAG="${SNAPD_TAG/linux-msft-snapd-/linux-msft-wsl-}" + gh release delete "$SNAPD_TAG" --repo "${{ github.repository }}" || true + git push origin ":refs/tags/$SNAPD_TAG" || true + git push origin ":refs/tags/$UPSTREAM_TAG" || true diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml new file mode 100644 index 0000000000000..82fca1c4c24d5 --- /dev/null +++ b/.github/workflows/sync-upstream.yml @@ -0,0 +1,74 @@ +name: 🔄 Sync with upstream + +on: + workflow_call: + outputs: + missing_tags: + description: The upstream tags that are missing locally + value: ${{ jobs.sync_upstream.outputs.missing_tags }} + snapd_tags: + description: The new tags that we need to create + value: ${{ jobs.sync_upstream.outputs.snapd_tags }} + +jobs: + sync_upstream: + runs-on: ubuntu-latest + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -yyq jq + - uses: actions/checkout@v3 + - name: Configure GIT + run: | + git config user.email 'actions@github.com' + git config user.name 'GitHub Actions' + git remote add upstream https://github.com/microsoft/WSL2-Linux-Kernel.git + - name: Sync from upstream + run: | + git fetch --tags origin + git fetch --tags --prune --progress --no-recurse-submodules upstream +refs/heads/master*:refs/remotes/upstream/master* + - name: Parse upstream tags + id: parse_tags + run: | + set -x + + REMOTE_TAGS="$(git show-ref --tags | awk '{print $2}' | cut -d/ -f3 | grep '^linux-msft-wsl-' || true)" + ORIGIN_TAGS="$(git ls-remote --tags origin | grep -v '\^{}' | cut -f2 | cut -d/ -f3 | grep '^linux-msft-wsl-' || true)" + + MISSING_TAGS="$(echo "$REMOTE_TAGS" | grep -v -F "$ORIGIN_TAGS" || true)" + + FILTERED_UPSTREAM_TAGS=() + FILTERED_SNAPD_TAGS=() + + for UPSTREAM_TAG in $MISSING_TAGS; do + # check that we have a non-empty string + [ -n "$UPSTREAM_TAG" ] || continue + + # check that the tag name matches the format we're expecting + echo "$UPSTREAM_TAG" | grep -Eq '^linux-msft-wsl-([0-9]+\.[0-9]+).*$' || continue + + # check that we haven't already built this tag + SNAPD_TAG="${UPSTREAM_TAG/linux-msft-wsl-/linux-msft-snapd-}" + [ -z "$(git tag -l "$SNAPD_TAG")" ] || continue + + FILTERED_UPSTREAM_TAGS+=($UPSTREAM_TAG) + FILTERED_SNAPD_TAGS+=($SNAPD_TAG) + done + + echo '::echo::on' + if [ "${#FILTERED_UPSTREAM_TAGS[@]}" -gt 0 ]; then + echo "::set-output name=missing_tags::$(jq --compact-output --null-input '$ARGS.positional' --args -- "${FILTERED_UPSTREAM_TAGS[@]}")" + echo "::set-output name=snapd_tags::$(jq --compact-output --null-input '$ARGS.positional' --args -- "${FILTERED_SNAPD_TAGS[@]}")" + else + echo "::set-output name=missing_tags::" + echo "::set-output name=snapd_tags::" + fi + - name: Rebase and push master; push tags + run: | + git rebase upstream/master + git push --force origin master + git push --force --tags origin + outputs: + missing_tags: ${{ steps.parse_tags.outputs.missing_tags }} + snapd_tags: ${{ steps.parse_tags.outputs.snapd_tags }} diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml new file mode 100644 index 0000000000000..43b09aeaf7551 --- /dev/null +++ b/.github/workflows/tag-release.yml @@ -0,0 +1,53 @@ +name: 🏷️ Re-tag new upstream release + +on: + workflow_call: + inputs: + missing_tags: + required: true + type: string + +jobs: + tag-release: + runs-on: ubuntu-latest + strategy: + matrix: + upstream_tag: ${{ fromJson(inputs.missing_tags) }} + steps: + - name: Build Variables + id: build_variables + env: + UPSTREAM_TAG: ${{ matrix.upstream_tag }} + run: | + # Work out which snapd-support branch we need to merge + SNAPD_TAG="${UPSTREAM_TAG/linux-msft-wsl-/linux-msft-snapd-}" + RELEASE_MINOR_VER="$(echo "$UPSTREAM_TAG" | sed -Ee 's/^linux-msft-wsl-([0-9]+\.[0-9]+).*$/\1/')" + + echo '::echo::on' + echo "::set-output name=snapd_support_branch::snapd-support-$RELEASE_MINOR_VER.y" + echo "::set-output name=snapd_tag::$SNAPD_TAG" + - uses: actions/checkout@v3 + with: + ref: ${{ matrix.upstream_tag }} + fetch-depth: 0 + - name: Configure GIT + run: | + git config user.email 'actions@github.com' + git config user.name 'GitHub Actions' + git remote add upstream https://github.com/microsoft/WSL2-Linux-Kernel.git + - name: Tag new release + run: | + set -x + + # Merge the snapd-support branch + git fetch --no-tags --prune --progress --no-recurse-submodules origin +refs/heads/"${{ steps.build_variables.outputs.snapd_support_branch }}"*:refs/remotes/origin/"${{ steps.build_variables.outputs.snapd_support_branch }}"* + git merge --no-edit "origin/${{ steps.build_variables.outputs.snapd_support_branch }}" + + # Tag the new release + git tag -f "${{ steps.build_variables.outputs.snapd_tag }}" + git push --tags --force + - name: Failure or cancellation cleanup + if: ${{ failure() || cancelled() }} + run: | + git push origin ":refs/tags/${{ steps.build_variables.outputs.snapd_tag }}" || true + git push origin ":refs/tags/${{ matrix.upstream_tag }}" || true