Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mirror filecoin built-in actors #344

Merged
merged 63 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0d9ac14
feat: mirror filecoin built-in actors
samuelarogbonlo Nov 16, 2023
2bc2381
make bucket name configurable
samuelarogbonlo Nov 16, 2023
17a483e
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Nov 16, 2023
8e03cea
test cloudflare
samuelarogbonlo Nov 16, 2023
c3f2dbf
test deploy cloudflare
samuelarogbonlo Nov 16, 2023
817563d
add slack token env and also make slack channel configurable
samuelarogbonlo Nov 16, 2023
b67964a
test deploy cloudflare
samuelarogbonlo Nov 16, 2023
a42ee6b
test deploy cloudflare
samuelarogbonlo Nov 16, 2023
8bdb6f4
test deploy mirror actors
samuelarogbonlo Nov 16, 2023
b9e17ee
remove wget download
samuelarogbonlo Nov 16, 2023
df59ea1
fix region upload error
samuelarogbonlo Nov 16, 2023
531899e
use different enviroment for slack alert
samuelarogbonlo Nov 16, 2023
b8f58cd
revert test deploy
samuelarogbonlo Nov 16, 2023
c48bb13
shorten slack message
samuelarogbonlo Nov 16, 2023
0fd16fb
nits: naming
samuelarogbonlo Nov 16, 2023
db154d1
nits: remove trailing region
samuelarogbonlo Nov 16, 2023
7cf269e
mirror releases weeks
samuelarogbonlo Dec 1, 2023
5dd0df4
fix ci
samuelarogbonlo Dec 1, 2023
f442790
fix ci
samuelarogbonlo Dec 1, 2023
b0f9ba6
add more comments and remove downloaded actors
samuelarogbonlo Dec 1, 2023
7cb2ac6
add more comments
samuelarogbonlo Dec 2, 2023
46b932b
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Dec 2, 2023
9eb7bc4
nits: improve comments
samuelarogbonlo Dec 3, 2023
4783d26
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Jan 2, 2024
0270e2a
nits: filter downloaded releases
samuelarogbonlo Jan 2, 2024
01b6612
nits: remove proof lost files
samuelarogbonlo Jan 2, 2024
d7c5765
fix: make review adjustment
samuelarogbonlo Jan 5, 2024
d4e598e
nits: more review changes
samuelarogbonlo Jan 8, 2024
718a724
nits: fix curl zero byte download
samuelarogbonlo Jan 9, 2024
ed891bb
nits: use secret variable
samuelarogbonlo Jan 10, 2024
2940dd2
chore: rewrite in python
samuelarogbonlo Jan 19, 2024
829adb3
ci fix working directory
samuelarogbonlo Jan 19, 2024
7a8183a
ci fix working directory
samuelarogbonlo Jan 19, 2024
329ee67
test deploy
samuelarogbonlo Jan 19, 2024
2991ace
fix wrong env name
samuelarogbonlo Jan 19, 2024
1d2b887
sily me forgetting to update new variables
samuelarogbonlo Jan 19, 2024
67ecd12
remove test py and mirror to cloudflare
samuelarogbonlo Jan 19, 2024
4aeffa5
nits
samuelarogbonlo Jan 19, 2024
28be1af
chore: add readme
samuelarogbonlo Jan 19, 2024
615571a
nits: docs updates
samuelarogbonlo Jan 21, 2024
4a8df74
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Jan 21, 2024
549ce30
nits: add docs to install
samuelarogbonlo Jan 22, 2024
5703465
feat: add linting ci
samuelarogbonlo Jan 22, 2024
a7fb7b9
fix wrong OS distro
samuelarogbonlo Jan 22, 2024
964a646
add install dep
samuelarogbonlo Jan 22, 2024
6a7a6d0
add sink logic to local system and s3
samuelarogbonlo Jan 23, 2024
b0875e4
test fail ci
samuelarogbonlo Jan 23, 2024
d0e286e
fix ci
samuelarogbonlo Jan 23, 2024
013f439
nits: add caching
samuelarogbonlo Jan 23, 2024
5e2b2fb
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Jan 23, 2024
d84f069
nits: local cache poetr install
samuelarogbonlo Jan 23, 2024
bccd80f
cache for cloudflare job
samuelarogbonlo Jan 23, 2024
18e9613
add missed if job for cloudflare
samuelarogbonlo Jan 23, 2024
1333ea6
chore: don't use s3 client when mirroring to local
samuelarogbonlo Jan 23, 2024
ccb2989
chore: reduce my over kill
samuelarogbonlo Jan 23, 2024
be30f94
improve mirror logic
samuelarogbonlo Jan 23, 2024
0858fa6
test mirror
samuelarogbonlo Jan 23, 2024
9f2599a
test mirror to do
samuelarogbonlo Jan 23, 2024
85fa13c
revert test mirror
samuelarogbonlo Jan 23, 2024
8f1aa5b
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Jan 23, 2024
0723d4c
test deployed cf
samuelarogbonlo Jan 24, 2024
0189aac
revert test
samuelarogbonlo Jan 24, 2024
ac94892
Merge branch 'main' into samuel/mirror-builtin-actors-releases
samuelarogbonlo Jan 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/mirror-builtin-actors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Mirror Builtin Actors Releases
on:
schedule:
- cron: '0 * * * *' # Runs every hour
pull_request:
paths:
- 'scripts/mirror-actors/**'
push:
paths:
- 'scripts/mirror-actors/**'
workflow_dispatch:

jobs:
mirror-releases-do:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true

- name: Install dependencies
working-directory: scripts/mirror-actors
run: poetry install --no-interaction --no-root

- name: Mirror Actors to DigitalOcean
working-directory: scripts/mirror-actors
if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
run: |
source .venv/bin/activate
python3 mirror_actors/
env:
SLACK_API_TOKEN: ${{ secrets.SLACK_TOKEN }}
SLACK_CHANNEL: "#forest-notifications"
BUCKET_NAME: filecoin-builtin-actors
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
REGION_NAME: fra1
ENDPOINT_URL: https://fra1.digitaloceanspaces.com

mirror-releases-cf:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true

- name: Install dependencies
working-directory: scripts/mirror-actors
run: poetry install --no-interaction --no-root

- name: Mirror Actors to CloudFlare
working-directory: scripts/mirror-actors
if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
run: |
source .venv/bin/activate
python3 mirror_actors/
env:
SLACK_API_TOKEN: ${{ secrets.SLACK_TOKEN }}
SLACK_CHANNEL: "#forest-notifications"
BUCKET_NAME: filecoin-builtin-actors
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_KEY }}
REGION_NAME: "auto"
ENDPOINT_URL: "https://2238a825c5aca59233eab1f221f7aefb.r2.cloudflarestorage.com"
21 changes: 21 additions & 0 deletions .github/workflows/scripts-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,24 @@ jobs:
yarn install
yarn lint
yarn js-check
run-py-linters:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true

- name: Install dependencies
working-directory: scripts/mirror-actors
run: poetry install --no-interaction --no-root

- name: Lint Python Code
working-directory: scripts/mirror-actors
run: poetry run pylint mirror_actors/ -f actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also add black as a formatter, and pylance as a type checker if you really want "production grade python".

Might not be relevant for quick scripts

Happy for this to be deferred as an issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see issue

46 changes: 46 additions & 0 deletions scripts/mirror-actors/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Overview
This project automates the process of mirroring Filecoin's built-in actors' releases from GitHub to cloud storage services (DigitalOcean Spaces and CloudFlare R2). The script checks for new releases on GitHub, downloads them, and uploads them to the specified cloud storage. It's designed to run periodically and ensures that the latest releases are always available in the cloud storage.


# Workflow

The project uses GitHub Actions for automated deployment:

- **Frequency**: The script runs every hour (0 * * * *).
- **Triggered By**: Changes in the scripts/mirror-actors/** path in the repository. This includes both pull requests and push events.
- **Manual Trigger**: The workflow can also be triggered manually via the GitHub UI (workflow_dispatch event).

# Manual deployments

## Requirements

### Software

* [Python3](https://www.python.org/downloads/)
* [Poetry](https://python-poetry.org/docs/)

For manual deployments, particularly useful for testing and debugging, set the following environment variables:

## Required environment variables

```bash
# DigitalOcean or CloudFlare Access Tokens depending which cloud you want to mirror to
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=

# Slack Access Token and channel
export SLACK_API_TOKEN=
export SLACK_CHANNEL=

# s3 Boto client Configurations
export BUCKET_NAME=
export REGION_NAME=
export ENDPOINT_URL=
```

Playbook:

```bash
$ poetry install --no-interaction --no-root # Install dependencies
$ poetry run python3 mirror_actors/ # Run the mirroring script
```
75 changes: 75 additions & 0 deletions scripts/mirror-actors/mirror_actors/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
This script mirrors Filecoin Actor releases from GitHub to an S3 bucket
and sends alerts to a Slack channel in case of failures.
"""

import os
import re
from datetime import datetime
import requests
from dateutil.relativedelta import relativedelta
import boto3
from slack_sdk.web import WebClient
from github import Github

# Define environment variables
SLACK_API_TOKEN = os.environ["SLACK_API_TOKEN"]
SLACK_CHANNEL = os.environ["SLACK_CHANNEL"]
S3_BUCKET = os.environ["S3_BUCKET"]
ENDPOINT_URL = os.environ["ENDPOINT_URL"]
REGION_NAME = os.environ["REGION_NAME"]

GITHUB_REPO = "filecoin-project/builtin-actors"
RELEASE_PATTERN = r'^v\d+\.\d+\.\d+.*$'

# Initialize clients
slack = WebClient(token=SLACK_API_TOKEN)
github = Github()
s3 = boto3.client('s3',
region_name=REGION_NAME,
endpoint_url=ENDPOINT_URL)

# Calculate the cutoff date (3 years ago from current date)
three_years_ago = datetime.now() - relativedelta(years=3)


def send_slack_alert(message):
"""
Send an alert message to a predefined Slack channel.

Args:
message (str): The message to be sent to Slack.
"""
slack.chat_postMessage(
channel=SLACK_CHANNEL,
text=message
).validate()

# Process GitHub releases
try:
releases = github.get_repo(GITHUB_REPO).get_releases()
# Fetch already mirrored objects from S3
s3_response = s3.list_objects(Bucket=S3_BUCKET)
already_mirrored = set()
if 'Contents' in s3_response:
already_mirrored = set(obj["Key"] for obj in s3_response["Contents"])

for release in releases:
tag_name = release.tag_name
# Removing timezone info for comparison
published_at = release.published_at.replace(tzinfo=None)
# Skip the release if it's older than 3 years
if published_at < three_years_ago:
continue

if re.match(RELEASE_PATTERN, tag_name):
for asset in release.get_assets():
key = f"{tag_name}/{asset.name}"
if key not in already_mirrored:
response = requests.get(asset.browser_download_url, timeout=30)
response.raise_for_status()
s3.put_object(Bucket=S3_BUCKET, Key=key, Body=response.content)

except Exception as e:
send_slack_alert(f"⛔ Filecoin Actor mirroring failed: {e}")
raise
Loading