A decentralized music tracking and discovery platform built on AT Protocol 🎵
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1name: build
2on:
3 push:
4 # The SDK binding tags only trigger bindings-release.yml (native libs → GitHub
5 # release); don't run the app build for them.
6 tags-ignore:
7 - "bindings-v*"
8 - "erlang-v*"
9 - "gleam-v*"
10
11jobs:
12 changes:
13 runs-on: ubuntu-latest
14 outputs:
15 api: ${{ steps.filter.outputs.api }}
16 rockskyd: ${{ steps.filter.outputs.rockskyd }}
17 embed: ${{ steps.filter.outputs.embed }}
18 feeds: ${{ steps.filter.outputs.feeds }}
19 ws: ${{ steps.filter.outputs.ws }}
20 mb: ${{ steps.filter.outputs.mb }}
21 steps:
22 - uses: actions/checkout@v4
23 - uses: dorny/paths-filter@v3
24 id: filter
25 with:
26 filters: |
27 api:
28 - 'apps/api/**'
29 - '.github/workflows/build.yml'
30 rockskyd:
31 - 'crates/**'
32 - 'Cargo.toml'
33 - 'Cargo.lock'
34 - '.github/workflows/build.yml'
35 embed:
36 - 'apps/embed/**'
37 - '.github/workflows/build.yml'
38 feeds:
39 - 'apps/feeds/**'
40 - '.github/workflows/build.yml'
41 ws:
42 - 'apps/ws/**'
43 - '.github/workflows/build.yml'
44 mb:
45 - 'musicbrainz/**'
46 - '.github/workflows/build.yml'
47
48 rockskyd:
49 needs: changes
50 if: needs.changes.outputs.rockskyd == 'true'
51 runs-on: ubuntu-latest
52 steps:
53 - uses: actions/checkout@v4
54 - name: Install system dependencies
55 run: |
56 sudo apt-get update && sudo apt-get install -y \
57 libreadline-dev \
58 pkg-config \
59 flex \
60 bison \
61 build-essential \
62 unzip
63 - name: Install DuckDB
64 run: |
65 DUCKDB_VERSION=1.4.0
66 curl -L -o /tmp/duckdb.zip \
67 https://github.com/duckdb/duckdb/releases/download/v${DUCKDB_VERSION}/libduckdb-linux-amd64.zip
68 sudo mkdir -p /usr/local/lib /usr/local/include
69 sudo unzip -o /tmp/duckdb.zip -d /tmp/duckdb
70 sudo cp /tmp/duckdb/libduckdb.so /usr/local/lib/
71 sudo cp /tmp/duckdb/duckdb.h /tmp/duckdb/duckdb.hpp /usr/local/include/
72 sudo ldconfig
73 - uses: dtolnay/rust-toolchain@stable
74 - uses: Swatinem/rust-cache@v2
75 with:
76 shared-key: rockskyd-release
77 cache-on-failure: true
78 - name: cargo build -p rockskyd --release
79 run: cargo build -p rockskyd --release
80 env:
81 DUCKDB_LIB_DIR: /usr/local/lib
82 DUCKDB_INCLUDE_DIR: /usr/local/include
83 - name: Upload rockskyd binary
84 uses: actions/upload-artifact@v4
85 with:
86 name: rockskyd
87 path: target/release/rockskyd
88 if-no-files-found: error
89
90 deploy:
91 needs: [changes, rockskyd]
92 if: |
93 always() &&
94 github.ref == 'refs/heads/main' &&
95 needs.rockskyd.result != 'failure' &&
96 (needs.rockskyd.result == 'success' ||
97 needs.changes.outputs.api == 'true' ||
98 needs.changes.outputs.embed == 'true' ||
99 needs.changes.outputs.feeds == 'true' ||
100 needs.changes.outputs.ws == 'true' ||
101 needs.changes.outputs.mb == 'true')
102 runs-on: ubuntu-latest
103 steps:
104 - name: Download rockskyd binary
105 if: needs.changes.outputs.rockskyd == 'true'
106 uses: actions/download-artifact@v4
107 with:
108 name: rockskyd
109 path: target/release
110 - name: Setup SSH
111 env:
112 SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
113 SSH_PUBLIC_KEY: ${{ secrets.SSH_PUBLIC_KEY }}
114 run: |
115 mkdir -p ~/.ssh
116 chmod 700 ~/.ssh
117 echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_ed25519
118 echo "$SSH_PUBLIC_KEY" | base64 -d > ~/.ssh/id_ed25519.pub
119 chmod 600 ~/.ssh/id_ed25519
120 chmod 644 ~/.ssh/id_ed25519.pub
121 ssh-keyscan -H ssh.rocksky.app >> ~/.ssh/known_hosts
122 - name: Pull latest on server
123 run: |
124 ssh root@ssh.rocksky.app 'cd /root/github/rocksky && git pull origin main && mkdir -p target/release'
125 - name: Build apps/api on server and restart
126 if: needs.changes.outputs.api == 'true'
127 env:
128 API_SERVICES: rocksky rocksky-xrpc
129 run: |
130 ssh root@ssh.rocksky.app "set -e; \
131 cd /root/github/rocksky/apps/api && \
132 /bin/bash -ic 'bun install --frozen-lockfile && bun run build'; \
133 systemctl restart $API_SERVICES; \
134 systemctl --no-pager --lines=0 status $API_SERVICES"
135 - name: Deploy rockskyd binary
136 if: needs.changes.outputs.rockskyd == 'true'
137 env:
138 ROCKSKYD_SERVICES: rocksky-jetstream rocksky-scrobbler rocksky-spotify rocksky-webscrobbler rocksky-navidrome
139 run: |
140 chmod +x target/release/rockskyd
141 scp target/release/rockskyd root@ssh.rocksky.app:/root/github/rocksky/target/release/rockskyd.new
142 ssh root@ssh.rocksky.app "set -e; \
143 systemctl stop $ROCKSKYD_SERVICES; \
144 mv /root/github/rocksky/target/release/rockskyd.new /root/github/rocksky/target/release/rockskyd; \
145 chmod +x /root/github/rocksky/target/release/rockskyd; \
146 systemctl start $ROCKSKYD_SERVICES; \
147 systemctl --no-pager --lines=0 status $ROCKSKYD_SERVICES"
148 - name: Restart rocksky-embed
149 if: needs.changes.outputs.embed == 'true'
150 run: |
151 ssh root@ssh.rocksky.app 'set -e; systemctl restart rocksky-embed; systemctl --no-pager --lines=0 status rocksky-embed'
152 - name: Restart rocksky-feeds
153 if: needs.changes.outputs.feeds == 'true'
154 run: |
155 ssh root@ssh.rocksky.app 'set -e; systemctl restart rocksky-feeds; systemctl --no-pager --lines=0 status rocksky-feeds'
156 - name: Restart rocksky-ws
157 if: needs.changes.outputs.ws == 'true'
158 run: |
159 ssh root@ssh.rocksky.app 'set -e; systemctl restart rocksky-ws; systemctl --no-pager --lines=0 status rocksky-ws'
160 - name: Restart rocksky-mb
161 if: needs.changes.outputs.mb == 'true'
162 run: |
163 ssh root@ssh.rocksky.app 'set -e; systemctl restart rocksky-mb; systemctl --no-pager --lines=0 status rocksky-mb'