Skip to content

Commit

Permalink
Update ipfs deploy workflow (#102)
Browse files Browse the repository at this point in the history
* update ipfs deploy workflow

* update hashes

* Update .github/workflows/ipfs-deploy.yml

Co-authored-by: KillariDev <[email protected]>

---------

Co-authored-by: KillariDev <[email protected]>
Co-authored-by: KillariDev <[email protected]>
  • Loading branch information
3 people authored Mar 12, 2024
1 parent 4491ca1 commit adf430d
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 20 deletions.
97 changes: 91 additions & 6 deletions .github/workflows/ipfs-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
name: IPFS deploy
name: Build and Push to IPFS

on:
workflow_dispatch:
push:
# Publish `master` as Docker `latest` image.
branches:
- master

# Publish `v1` tags as releases.
tags:
- 'v\d+'

Expand All @@ -10,10 +15,12 @@ env:
REGISTRY: ghcr.io

jobs:
deploy-to-prod:
# Push image to GitHub Packages.
# See also https://docs.docker.com/docker-hub/builds/
push:
runs-on: ubuntu-latest
environment:
name: deploy/prod
if: github.event_name == 'push'

steps:
- uses: actions/checkout@v2

Expand All @@ -22,7 +29,7 @@ jobs:

- name: Build image
run: |
docker build . --file Dockerfile --tag $IMAGE_TAG
docker build --file Dockerfile --tag $IMAGE_TAG .
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
Expand Down Expand Up @@ -50,3 +57,81 @@ jobs:
docker tag $IMAGE_TAG $IMAGE_ID:$VERSION
docker push $IMAGE_ID:$VERSION
# Make image reference available to subsequent steps
echo "IMAGE_RELEASE_ID=$(echo $IMAGE_ID:$VERSION)" >> $GITHUB_ENV
# Run docker image script to publish app to nft.storage
- name: Publish to nft.storage
run: |
docker run -e NFTSTORAGE_API_KEY=${{ secrets.NFTSTORAGE_API_KEY }} $IMAGE_RELEASE_ID nft.storage
- name: Create a reference for IPFS hash
if: github.ref_type == 'tag'
run: |
echo "IPFS_HASH=$(docker run --entrypoint /bin/sh $IMAGE_RELEASE_ID -c 'cat /ipfs_hash.txt')" >> $GITHUB_ENV
- name: Create a release
if: github.ref_type == 'tag'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Markdown template for the release notes
RELEASE_NOTE_TEMPLATE=$(cat << EOF
#### IPFS Hash
\`\`\`
$IPFS_HASH
\`\`\`
You can view published versions of Horswap through any IPFS Gateway
[ipfs://$IPFS_HASH](ipfs://$IPFS_HASH) __(Recommended)__
_requires Brave Browser or IPFS Desktop_
[https://$IPFS_HASH.ipfs.nftstorage.link](https://$IPFS_HASH.ipfs.nftstorage.link)
[https://$IPFS_HASH.ipfs.zoltu.io](https://$IPFS_HASH.ipfs.zoltu.io)
[https://$IPFS_HASH.ipfs.keydonix.com](https://$IPFS_HASH.ipfs.keydonix.com)
[https://$IPFS_HASH.ipfs.cf-ipfs.com](https://$IPFS_HASH.ipfs.cf-ipfs.com)
[https://$IPFS_HASH.ipfs.w3s.link](https://$IPFS_HASH.ipfs.w3s.link)
EOF
)
# Generate payload for creating a new release
PAYLOAD_TEMPLATE=$(cat <<EOF
{
"name": "$GITHUB_REF_NAME",
"tag_name": "$GITHUB_REF_NAME",
"body": $(echo "$RELEASE_NOTE_TEMPLATE" | jq -cRs '@json|fromjson'),
"draft": false,
"generate_release_notes": true
}
EOF
)
# Create a github release
# https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release
REQUEST_DATA=$(echo "$PAYLOAD_TEMPLATE" | jq -c)
RESPONSE=$(curl \
--silent \
--location \
--request POST \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer $GITHUB_TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28" \
--data "$REQUEST_DATA" \
--write-out "%{http_code}" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/releases"
)
# Extract the response body and the appended http code
RESPONSE_CODE=${RESPONSE: -3}
RESPONSE_BODY=${RESPONSE//$RESPONSE_CODE/}
# Successful creation will return a status 201 (Created), otherwise show the error
if [ "$RESPONSE_CODE" -ne 201 ]; then
ERROR_MESSAGE=$(echo "$RESPONSE_BODY" | jq '.message')
echo "HTTP $RESPONSE_CODE - $ERROR_MESSAGE"
exit 1
fi
echo "Release ($GITHUB_REF_NAME) successfully created"
93 changes: 83 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# ---------------------------------------------
# App Setup: Install dependencies and build app
# ---------------------------------------------

FROM node:18.19.0-alpine3.18@sha256:c0a5f02df6e631b75ee3037bd4389ac1f91e591c5c1e30a0007a7d0babcd4cd3 as builder

# Get git
Expand All @@ -21,28 +25,97 @@ COPY ./.eslintrc.js /source/.eslintrc.js
COPY ./.swcrc /source/.swcrc
RUN yarn run build

# --------------------------------------------------------
# Base Image: Create the base image that will host the app
# --------------------------------------------------------

# Cache the kubo image
FROM ipfs/kubo:v0.25.0@sha256:0c17b91cab8ada485f253e204236b712d0965f3d463cb5b60639ddd2291e7c52 as ipfs-kubo

# Create the base image
FROM debian:12.2-slim@sha256:93ff361288a7c365614a5791efa3633ce4224542afb6b53a1790330a8e52fc7d

# Add curl to the base image (7.88.1-10+deb12u5)
# Add jq to the base image (1.6-2.1)
RUN apt-get update && apt-get install -y curl=7.88.1-10+deb12u5 jq=1.6-2.1

# Install kubo and initialize ipfs
COPY --from=ipfs-kubo /usr/local/bin/ipfs /usr/local/bin/ipfs

# Copy app's build output and initialize IPFS api
COPY --from=builder /source/build /export
RUN ipfs init
RUN ipfs add --cid-version 1 --quieter --only-hash -r /export > ipfs_hash.txt

# Copy build output
COPY --from=builder /source/build /export
# --------------------------------------------------------
# Publish Script: Option to host app locally or on nft.storage
# --------------------------------------------------------

WORKDIR ~
COPY <<'EOF' /entrypoint.sh
#!/bin/sh
set -e

if [ $# -ne 1 ]; then
echo "Example usage: docker run --rm ghcr.io/darkflorist/horswap:latest [docker-host|nft.storage]"
exit 1
fi

case $1 in

docker-host)
# Show the IFPS build hash
echo "Build Hash: $(cat /ipfs_hash.txt)"

# Determine the IPV4 address of the docker-hosted IPFS instance
IPFS_IP4_ADDRESS=$(getent ahostsv4 host.docker.internal | grep STREAM | head -n 1 | cut -d ' ' -f 1)

echo "Adding files to docker running IPFS at $IPFS_IP4_ADDRESS"
IPFS_HASH=$(ipfs add --api /ip4/$IPFS_IP4_ADDRESS/tcp/5001 --cid-version 1 --quieter -r /export)
echo "Uploaded Hash: $IPFS_HASH"
;;

nft.storage)
if [ -z $NFTSTORAGE_API_KEY ] || [ $NFTSTORAGE_API_KEY = "" ]; then
echo "NFTSTORAGE_API_KEY environment variable is not set";
exit 1;
fi

# Show the IFPS build hash
echo "Build Hash: $(cat /ipfs_hash.txt)"

# Create a CAR archive from build hash
echo "Uploading files to nft.storage..."
IPFS_HASH=$(ipfs add --cid-version 1 --quieter -r /export)
ipfs dag export $IPFS_HASH > output.car

# Upload the entire directory to nft.storage
UPLOAD_RESPONSE=$(curl \
--request POST \
--header "Authorization: Bearer $NFTSTORAGE_API_KEY" \
--header "Content-Type: application/car" \
--data-binary @output.car \
--silent \
https://api.nft.storage/upload)

# Show link to nft.storage (https://xxx.ipfs.nftstorage.link)
UPLOAD_SUCCESS=$(echo "$UPLOAD_RESPONSE" | jq -r ".ok")

# add the build output to IPFS and write the hash to a file
RUN ipfs add --cid-version 1 --quieter --only-hash --recursive /export > ipfs_hash.txt
if [ "$UPLOAD_SUCCESS" = "true" ]; then
echo "Succesfully uploaded to https://"$(echo "$UPLOAD_RESPONSE" | jq -r ".value.cid")".ipfs.nftstorage.link"
else
echo "Upload Failed: " $(echo "$UPLOAD_RESPONSE" | jq -r ".error | @json")
fi
;;

# print the hash for good measure in case someone is looking at the build logs
RUN cat ipfs_hash.txt
*)
echo "Invalid option: $1"
echo "Example usage: docker run --rm ghcr.io/darkflorist/horswap:latest [docker-host|nft.storage]"
exit 1
;;
esac
EOF

# this entrypoint file will execute `ipfs add` of the build output to the docker host's IPFS API endpoint, so we can easily extract the IPFS build out of the docker image
RUN printf '#!/bin/sh\nipfs --api /ip4/`getent ahostsv4 host.docker.internal | grep STREAM | head -n 1 | cut -d \ -f 1`/tcp/5001 add --cid-version 1 -r /export' >> entrypoint.sh
RUN chmod u+x entrypoint.sh
RUN chmod u+x /entrypoint.sh

ENTRYPOINT [ "./entrypoint.sh" ]
ENTRYPOINT [ "/entrypoint.sh" ]
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ exports[`EmptyWalletContent.tsx matches base snapshot 1`] = `
/>
</svg>
<div
class="c1 c2 common__127l8hd0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
class="c1 c2 common__1cp2nzo0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
>
No NFTs yet
</div>
Expand Down Expand Up @@ -128,7 +128,7 @@ exports[`EmptyWalletContent.tsx matches base snapshot 1`] = `
/>
</svg>
<div
class="c1 c2 common__127l8hd0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
class="c1 c2 common__1cp2nzo0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
>
No tokens yet
</div>
Expand Down Expand Up @@ -174,7 +174,7 @@ exports[`EmptyWalletContent.tsx matches base snapshot 1`] = `
/>
</svg>
<div
class="c1 c2 common__127l8hd0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
class="c1 c2 common__1cp2nzo0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
>
No activity yet
</div>
Expand Down Expand Up @@ -209,7 +209,7 @@ exports[`EmptyWalletContent.tsx matches base snapshot 1`] = `
/>
</svg>
<div
class="c1 c2 common__127l8hd0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
class="c1 c2 common__1cp2nzo0 sprinkles_fontWeight_medium_sm__1jkzbi5d9 sprinkles_fontSize_28_sm__1jkzbi5bx sprinkles_lineHeight_36_sm__1jkzbi5el css-n8z49y"
>
No pools yet
</div>
Expand Down

0 comments on commit adf430d

Please sign in to comment.