name: Release

on:
  create:
    tags:
      - v*

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: "1.21.5"
      - name: Test
        run: go test ./...
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v4
        with:
          version: v1.14.1
          args: release --rm-dist
        env:
          GITHUB_TOKEN: ${{ secrets.RELEASE_GH_TOKEN }}
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
      - name: Upload Build Artifacts
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: dist
  publishToDepo:
    name: Publish to Depo
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download Build Artifacts
        uses: actions/download-artifact@v3
        with:
          name: dist
          path: dist
      - name: Build Debian/RPM/APK repositories
        # Manually build unsigned Debian, RPM and APK repositories
        # For Debian (the key needs to be *not* armored):
        #   deb [signed-by=/etc/apt/keyrings/nextdns.gpg] https://repo.nextdns.io/deb stable main
        # For yum:
        #   yum-config-manager --add-repo https://repo.nextdns.io/nextdns.repo
        # For zypper:
        #   zypper ar -f https://repo.nextdns.io/nextdns.repo nextdns
        # For Alpine
        #   curl -s https://repo.nextdns.io/nextdns.pub > /etc/apk/keys/nextdns.pub
        #   echo https://repo.nextdns.io/apk > /etc/apk/repositories
        run: |
          echo "::group::Install packages"
          sudo apt-get -qyy install gzip apt-utils gnupg > /dev/null
          echo "::endgroup::"
          cd dist
          mkdir -p r/deb/pool r/rpm r/apk
          for d in *.deb; do
            pkg=${d%_linux_*}
            arch=${d#*linux_}
            arch=${arch%.deb}
            case $arch in
              386) deb_arch=i386;;
              amd64) deb_arch=amd64;;
              armv5) deb_arch=armel;;
              armv6) deb_arch=armhf;;
              arm64) deb_arch=arm64;;
              mips*_hardfloat) deb_arch=;;
              mips64le_*) deb_arch=mips64el;;
              mipsle_*) deb_arch=mipsel;;
              mips_*) deb_arch=mips;;
              *) deb_arch=;;
            esac
            case $arch in
              386) rpm_arch=i686;;
              amd64) rpm_arch=x86_64;;
              armv7) rpm_arch=armhfp;;
              arm64) rpm_arch=aarch64;;
              *) rpm_arch=;;
            esac
            case $arch in
              386) alpine_arch=x86;;
              amd64) alpine_arch=x86_64;;
              armv6) alpine_arch=armhf;;
              armv7) alpine_arch=armv7;;
              arm64) alpine_arch=aarch64;;
              *) alpine_arch=;;
            esac
            echo "::group::Handle repository actions for $arch"
            if [ "$deb_arch" ]; then
              echo "Debian: ${deb_arch}"
              cp $d r/deb/pool/${pkg}_${deb_arch}.deb
              (
              cd r/deb
              mkdir -p dists/stable/main/binary-${deb_arch}
              apt-ftparchive --arch $deb_arch packages pool \
                | sed "s/^Architecture:.*/Architecture: ${deb_arch}/" \
                > dists/stable/main/binary-${deb_arch}/Packages
              gzip -k dists/stable/main/binary-${deb_arch}/Packages
              )
            fi
            if [ "$rpm_arch" ]; then
              echo "RPM: ${rpm_arch}"
              cp ${d%.deb}.rpm r/rpm/${pkg}_${rpm_arch}.rpm
            fi
            if [ "$alpine_arch" ]; then
              echo "Alpine: ${alpine_arch}"
              mkdir -p r/apk/$alpine_arch
              cp ${d%.deb}.apk r/apk/$alpine_arch/nextdns-${pkg#nextdns_}.apk
            fi
            echo "::endgroup::"
          done
          echo "::group::Create Debian release file"
          (
            cd r/deb
            echo Origin: NextDNS
            echo Label: NextDNS
            echo Suite: stable
            echo Components: main
            apt-ftparchive release dists/stable
          ) > r/deb/dists/stable/Release
          echo "::endgroup::"
          echo "::group::Create RPM repository"
          (
            cd r/rpm
            # No createrepo available in Ubuntu 20.04
            docker run --rm -w $PWD -v $PWD:$PWD almalinux:8 \
              sh -c "yum install -y createrepo &&
                     createrepo . &&
                     chown -R $(id -u):$(id -g) ."
          )
          cat <<EOF > r/nextdns.repo
          [nextdns]
          name=nextdns
          baseurl=https://repo.nextdns.io/rpm
          enabled=1
          gpgcheck=0
          repo_gpgcheck=1
          gpgkey=https://repo.nextdns.io/nextdns-armored.gpg
          EOF
          echo "::endgroup::"
          echo "::group::Create APK index files"
          (
            cd r/apk
            docker run --rm -w $PWD -v $PWD:$PWD alpine:latest sh -c '
              for arch in */; do
                echo "Indexing $arch"
                (
                  cd $arch
                  apk index -o APKINDEX.unsigned.tar.gz *.apk
                )
              done
            '
          )
          echo "::endgroup::"
      - name: Sign repositories
        # Key should be exported with:
        #  gpg --armor --export-secret-keys nextdns@nextdns.io
        run: |
          echo "::group::Preparing keys"
          cd dist/r
          echo "$GPG_KEY" | gpg --import
          gpg --export > nextdns.gpg
          gpg --export --armor > nextdns-armored.gpg
          echo "$REPO_KEY" > /tmp/nextdns
          openssl rsa -in /tmp/nextdns -pubout > nextdns.pub
          echo "::endgroup::"

          echo "::group::Signing Debian repository"
          gpg --output deb/dists/stable/Release.gpg --detach-sign deb/dists/stable/Release
          gpg --output deb/dists/stable/InRelease --clearsign --detach-sign deb/dists/stable/Release
          echo "::endgroup::"

          echo "::group::Signing RPM repository"
          gpg --detach-sign --armor rpm/repodata/repomd.xml
          echo "::endgroup::"

          echo "::group::Signing APK repository"
          docker run --rm -w $PWD -v $PWD:$PWD -v /tmp/nextdns:/tmp/nextdns alpine:latest sh -c '
            apk add alpine-sdk
            cd apk
            for arch in */; do
              cp $arch/APKINDEX.unsigned.tar.gz $arch/APKINDEX.tar.gz
              abuild-sign -k /tmp/nextdns $arch/APKINDEX.tar.gz
            done
          '
          echo "::endgroup::"
        env:
          GPG_KEY: ${{ secrets.GPG_KEY }}
          REPO_KEY: ${{ secrets.REPO_KEY }}
      - name: Publish repositories
        run: |
          cd dist
          aws s3 sync --no-progress --exclude "*" --include "*.deb" --include "*.rpm" --include "*.apk" \
            --storage-class REDUCED_REDUNDANCY --acl public-read r/ s3://${AWS_BUCKET}/
          aws s3 sync --no-progress \
            --storage-class REDUCED_REDUNDANCY --acl public-read r/ s3://${AWS_BUCKET}/
          aws s3 sync --no-progress --delete \
            --storage-class REDUCED_REDUNDANCY --acl public-read r/ s3://${AWS_BUCKET}/
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.S3_REPO_KEY }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_REPO_SECRET }}
          AWS_DEFAULT_REGION: us-east-1
          AWS_BUCKET: repo.nextdns.io
  publishToOpenWRT:
    name: Publish to OpenWRT
    needs: publishToDepo
    runs-on: ubuntu-latest
    strategy:
      matrix:
        openwrt-branch: ["master", "openwrt-22.03", "openwrt-23.05"]
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set environment variables
        run: |
          TAG=$(echo $GITHUB_REF | sed 's/refs\/tags\///')
          VERSION=${TAG:1}
          AUTHOR_NAME="Olivier Poitrey"
          AUTHOR_EMAIL=rs@nextdns.io

          OPENWRT_HASH=$(curl -sL "https://codeload.github.com/nextdns/nextdns/tar.gz/${TAG}" | sha256sum | cut -d' ' -f1)

          if [ "${{ matrix.openwrt-branch }}" == "master" ]; then 
            export PR_TITLE="nextdns: Update to version $VERSION";
          else 
            BACKPORT_VERSION=$(echo ${{ matrix.openwrt-branch }} | sed 's/openwrt-//')
            export PR_TITLE="[$BACKPORT_VERSION] nextdns: Update to version $VERSION";
          fi

          echo "OPENWRT_HASH=$OPENWRT_HASH"

          echo "OPENWRT_HASH=$OPENWRT_HASH" >> $GITHUB_ENV
          echo "VERSION=$VERSION" >> $GITHUB_ENV
          echo "AUTHOR_NAME=$AUTHOR_NAME" >> $GITHUB_ENV
          echo "AUTHOR_EMAIL=$AUTHOR_EMAIL" >> $GITHUB_ENV
          echo "PR_TITLE=$PR_TITLE" >> $GITHUB_ENV
      - name: Checkout OpenWRT packages repository fork
        uses: actions/checkout@v3
        with:
          repository: openwrt/packages
          ref: ${{ matrix.openwrt-branch }}
      - name: Rebase fork
        run: |
          git remote add upstream https://github.com/openwrt/packages.git
          git fetch upstream
          git reset --hard upstream/${{ matrix.openwrt-branch }}
      - name: Update nextdns Makefile
        run: |
          sed -E -i 's/PKG_SOURCE_PROTO:=.*/PKG_SOURCE:=nextdns-$(PKG_VERSION).tar.gz/' net/nextdns/Makefile
          sed -i 's/PKG_VERSION:=.*/PKG_VERSION:=${{ env.VERSION }}/' net/nextdns/Makefile
          sed -i 's/PKG_RELEASE:=.*/PKG_RELEASE:=1/' net/nextdns/Makefile
          sed -i 's!PKG_SOURCE_URL:=.*!PKG_SOURCE_URL:=https://codeload.github.com/nextdns/nextdns/tar.gz/v$(PKG_VERSION)?!' net/nextdns/Makefile
          sed -i 's/PKG_.*HASH:=.*/PKG_HASH:=${{ env.OPENWRT_HASH }}/' net/nextdns/Makefile
      - name: Create pull request towards OpenWRT - ${{ matrix.openwrt-branch }}
        uses: peter-evans/create-pull-request@v4
        with:
          token: ${{ secrets.RELEASE_GH_TOKEN }}
          commit-message: |
            nextdns: Update to version ${{ env.VERSION }}

            Signed-off-by: ${{ env.AUTHOR_NAME }} <${{ env.AUTHOR_EMAIL }}>
          title: ${{ env.PR_TITLE }}
          branch: nextdns-${{ env.VERSION }}-${{ matrix.openwrt-branch }}
          body: Update to version ${{ env.VERSION }}
          base: ${{ matrix.openwrt-branch }}
          author: ${{ env.AUTHOR_NAME }} <${{ env.AUTHOR_EMAIL }}>
          push-to-fork: rs/openwrt-packages
