VERSION 0.8
PROJECT earthly-technologies/core
FROM alpine:3.18

deps:
    FROM ubuntu:20.04
    # for apt to be noninteractive
    ENV DEBIAN_FRONTEND noninteractive
    ENV DEBCONF_NONINTERACTIVE_SEEN true
    RUN apt-get update && apt-get install -y dpkg-dev wget dpkg-sig

deb:
    ARG RELEASE_TAG
    ARG EARTHLY_PLATFORM
    RUN test ! -z "$EARTHLY_PLATFORM" || (echo "EARTHLY_PLATFORM is required" && exit 1)
    ARG RELEASE_TAG_WITHOUT_V=$(echo "$RELEASE_TAG" | cut -c 2-)
    ARG PKG_NAME=earthly_${RELEASE_TAG_WITHOUT_V}-1_${EARTHLY_PLATFORM}
    FROM +deps
    WORKDIR /work
    RUN mkdir -p $PKG_NAME/DEBIAN
    RUN mkdir -p $PKG_NAME/usr/bin/
    RUN (echo "$RELEASE_TAG" | grep '^v[0-9]\+.[0-9]\+.[0-9]\+$' > /dev/null) || (echo "RELEASE_TAG must be formatted as v1.2.3; instead got \"$RELEASE_TAG\""; exit 1)
    RUN wget -q "https://github.com/earthly/earthly/releases/download/${RELEASE_TAG}/earthly-linux-$EARTHLY_PLATFORM" -O $PKG_NAME/usr/bin/earthly && chmod +x $PKG_NAME/usr/bin/earthly
    COPY earthly.control $PKG_NAME/DEBIAN/control
    COPY postinst $PKG_NAME/DEBIAN/postinst
    COPY postrm $PKG_NAME/DEBIAN/postrm
    RUN chmod 0555 $PKG_NAME/DEBIAN/postinst $PKG_NAME/DEBIAN/postrm
    RUN sed -i "s/__earthly_version__/$RELEASE_TAG_WITHOUT_V/" $PKG_NAME/DEBIAN/control
    RUN dpkg -b $PKG_NAME
    SAVE ARTIFACT $PKG_NAME.deb AS LOCAL output/debs/$PKG_NAME.deb

deb-amd64:
    COPY \
        --build-arg  EARTHLY_PLATFORM=amd64 \
        +deb/* ./
    SAVE ARTIFACT *.deb

deb-arm64:
    COPY \
        --build-arg  EARTHLY_PLATFORM=arm64 \
        +deb/* ./
    SAVE ARTIFACT *.deb

deb-all:
    COPY +deb-amd64/*.deb .
    COPY +deb-arm64/*.deb .
    SAVE ARTIFACT ./*.deb

# If for any reason you need to generate a new PGP key, it can be done with
# this target; however this has already been done once, and our official key has
# been saved under /release/keys/earthly-private.pgp (and earthly-public.pgp)
generate-new-gpg-key:
    FROM +deps
    WORKDIR /root/pgp-key
    RUN echo "%echo Generating a basic OpenPGP key
Key-Type: RSA
Key-Length: 4096
Name-Real: earthly
Name-Email: support@earthly.dev
Expire-Date: 0
%no-ask-passphrase
%no-protection
%commit
%echo done" > earthly-pgp.batch
    RUN rm -rf /root/gpupg && gpg --no-tty --batch --gen-key earthly-pgp.batch
    RUN gpg --output earthly-pgp-public.pgp --armor --export support@earthly.dev
    RUN gpg --output earthly-pgp-private.pgp --armor --export-secret-key support@earthly.dev
    SAVE ARTIFACT earthly-pgp-public.pgp AS LOCAL earthly-pgp-public.pgp
    SAVE ARTIFACT earthly-pgp-private.pgp AS LOCAL earthly-pgp-private.pgp

download:
    FROM ../common-repo+aws
    ARG --required S3_BUCKET
    RUN --no-cache \
        --secret MFA_ARN=+secrets/user/earthly-technologies/aws/mfa-arn \
        --secret MFA_KEY=+secrets/user/earthly-technologies/aws/mfa-key \
        --mount type=secret,id=+secrets/user/earthly-technologies/aws/credentials,target=/root/.aws/credentials \
        eval $(assume-developer-role) && \
        aws s3 cp --recursive "s3://$S3_BUCKET/deb/" repo
    SAVE ARTIFACT repo AS LOCAL output/repo

index-and-sign:
    FROM +deps
    ARG USE_OUTPUT_COPY=true
    IF [ "$USE_OUTPUT_COPY" = "true" ]
        RUN echo "upload using local target"
        COPY output/repo /repo
    ELSE
        RUN echo "upload using container target"
        COPY +deb-all/*.deb /debs/.
        COPY +download/repo /repo
        RUN cp /debs/*.deb /repo/pool/main/.
    END

    # validate the repo directory structure is correct
    RUN (test $(ls -1 /repo/pool) = "main") || (echo "pool should only contain a single directory named main"; exit 1)
    RUN ls /repo/pool/main/*.deb || (echo "directory does not contain debs"; exit 1)
    RUN (test $(ls -1 /repo/pool/main | grep -v '\.deb$' | wc -l) = 0) || (echo "directory should only contain debs, but doesn't"; exit 1)

    WORKDIR /repo
    RUN rm -rf dists
    RUN mkdir -p dists/stable/main/binary-amd64
    RUN mkdir -p dists/stable/main/binary-arm64

    RUN dpkg-scanpackages --arch amd64 --multiversion pool/ > dists/stable/main/binary-amd64/Packages
    RUN dpkg-scanpackages --arch arm64 --multiversion pool/ > dists/stable/main/binary-arm64/Packages

    RUN gzip -c9 dists/stable/main/binary-amd64/Packages > dists/stable/main/binary-amd64/Packages.gz
    RUN gzip -c9 dists/stable/main/binary-arm64/Packages > dists/stable/main/binary-arm64/Packages.gz

    WORKDIR /repo/dists/stable
    COPY generate-release.sh /
    RUN rm -f InRelease Release.gpg
    RUN /generate-release.sh > Release

    # basic validation that files are in the right places.
    RUN set -e; \
        grep amd64 Release; \
        grep arm64 Release; \
        ls /repo/pool/main/earthly_*.deb; \
        ls /repo/dists/stable/Release;

    # Next move on to signing it
    RUN \
        --mount type=secret,id=release/keys/earthly-private.pgp,target=/release-key/earthly-private.pgp \
        gpg --import /release-key/earthly-private.pgp
    RUN gpg --default-key earthly-apt -abs -o /repo/dists/stable/Release.gpg /repo/dists/stable/Release
    RUN cat /repo/dists/stable/Release | gpg --default-key earthly-apt -abs --clearsign --no-emit-version > /repo/dists/stable/InRelease

    SAVE ARTIFACT /repo AS LOCAL output/signed-repo

upload:
    FROM ../common-repo+aws

    ARG USE_OUTPUT_COPY=true
    IF [ "$USE_OUTPUT_COPY" = "true" ]
        RUN echo "upload using local target"
        COPY output/signed-repo /repo
    ELSE
        RUN echo "upload using container target"
        COPY +index-and-sign/repo /repo
    END

    RUN if (find /repo | grep -i private); then \
            echo "found a file in /repo containing the string private; breaking as we probably shouldn't upload this file to s3"; \
            exit 1; \
        fi
    # upload public key
    ARG --required S3_BUCKET
    RUN --push \
        --mount type=secret,id=release/keys/earthly-public.pgp,target=/release-key/earthly-public.pgp \
        --secret MFA_ARN=+secrets/user/earthly-technologies/aws/mfa-arn \
        --secret MFA_KEY=+secrets/user/earthly-technologies/aws/mfa-key \
        --mount type=secret,id=+secrets/user/earthly-technologies/aws/credentials,target=/root/.aws/credentials \
        grep PUBLIC /release-key/earthly-public.pgp >/dev/null && \
        eval $(assume-developer-role 1) && \
        aws s3 cp --acl public-read /release-key/earthly-public.pgp "s3://$S3_BUCKET/earthly.pgp" && \
        # upload signed repo
        # Note: aws s3 sync doesn't always pickup changes to Release and Packages files, so force a cp to ensure they are uploaded
        aws s3 cp --acl public-read /repo/dists/stable/Release s3://$S3_BUCKET/deb/dists/stable/Release && \
        aws s3 cp --acl public-read /repo/dists/stable/Release.gpg s3://$S3_BUCKET/deb/dists/stable/Release.gpg && \
        aws s3 cp --acl public-read /repo/dists/stable/InRelease s3://$S3_BUCKET/deb/dists/stable/InRelease && \
        aws s3 cp --acl public-read /repo/dists/stable/main/binary-amd64/Packages s3://$S3_BUCKET/deb/dists/stable/main/binary-amd64/Packages && \
        aws s3 cp --acl public-read /repo/dists/stable/main/binary-arm64/Packages s3://$S3_BUCKET/deb/dists/stable/main/binary-arm64/Packages && \
        aws s3 cp --acl public-read /repo/dists/stable/main/binary-amd64/Packages.gz s3://$S3_BUCKET/deb/dists/stable/main/binary-amd64/Packages.gz && \
        aws s3 cp --acl public-read /repo/dists/stable/main/binary-arm64/Packages.gz s3://$S3_BUCKET/deb/dists/stable/main/binary-arm64/Packages.gz && \
        aws s3 sync --acl public-read /repo s3://$S3_BUCKET/deb/

build-and-release:
    ARG --required S3_BUCKET
    BUILD +upload --USE_OUTPUT_COPY=false --S3_BUCKET="$S3_BUCKET"
