Skip to content

Deploy

Deploy #57

Workflow file for this run

name: Deploy
# Manual for now. Uncomment the release trigger once the server + secrets are set up.
on:
workflow_dispatch:
# release:
# types: [published]
permissions:
contents: read
packages: write # push images to ghcr.io/bitmono-project
# Required repo/org secrets:
# SSH_PRIVATE_KEY, SERVER_HOST, SERVER_USER, SSH_PORT, DATABASE_PASSWORD, REDIS_PASSWORD, SENTRY_DSN
# Optional (crackmes gallery — each enables its feature; unset = disabled):
# DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET (Discord OAuth login)
# GH_OAUTH_CLIENT_ID, GH_OAUTH_CLIENT_SECRET (GitHub OAuth login; GH_ prefix — GITHUB_* is reserved)
# TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEY (Cloudflare Turnstile captcha on upload)
# CRACKME_ZIP_PASSWORD (download zip password; defaults to bitmono.dev)
# DISCORD_WEBHOOK_URL (channel webhook — announces new challenges + solves)
# WECHALL_AUTH_KEY (WeChall site-connector shared secret — /api/wechall validate+score)
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: "10.0.x"
- name: Install Aspire CLI
run: curl -sSL https://aspire.dev/install.sh | bash
- name: Setup SSH agent
uses: webfactory/ssh-agent@v0.10.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Set environment variables
run: |
echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
echo "OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV
echo "APP_VERSION=build.${{ github.run_number }}.${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: aspire deploy
working-directory: BitMono.Web.AppHost
run: aspire deploy -e Production
env:
# SSH target
DockerSSH__TargetHost: ${{ secrets.SERVER_HOST }}
DockerSSH__SshUsername: ${{ secrets.SERVER_USER }}
DockerSSH__SshPort: ${{ secrets.SSH_PORT }}
# Container registry (GitHub Container Registry under the org)
DockerRegistry__RegistryUrl: ghcr.io
DockerRegistry__RepositoryPrefix: bitmono-project/web
DockerRegistry__RegistryUsername: ${{ github.actor }}
DockerRegistry__RegistryPassword: ${{ secrets.GITHUB_TOKEN }}
# Remote deploy path
Deployment__RemoteDeployPath: /opt/bitmono/web
IMAGE_TAG_SUFFIX: ${{ env.APP_VERSION }}
OWNER_LC: ${{ env.OWNER_LC }}
# Secret parameters (AppHost AddParameter)
Parameters__DatabasePassword: ${{ secrets.DATABASE_PASSWORD }}
Parameters__RedisPassword: ${{ secrets.REDIS_PASSWORD }}
# Crackmes gallery — OAuth, Turnstile captcha, download-zip password (all optional)
Parameters__DiscordClientId: ${{ secrets.DISCORD_CLIENT_ID }}
Parameters__DiscordClientSecret: ${{ secrets.DISCORD_CLIENT_SECRET }}
Parameters__GitHubClientId: ${{ secrets.GH_OAUTH_CLIENT_ID }}
Parameters__GitHubClientSecret: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
Parameters__TurnstileSiteKey: ${{ secrets.TURNSTILE_SITE_KEY }}
Parameters__TurnstileSecretKey: ${{ secrets.TURNSTILE_SECRET_KEY }}
Parameters__ZipPassword: ${{ secrets.CRACKME_ZIP_PASSWORD }}
# Sentry/Bugsink DSN — Parameters__ so AppHost.WireParam forwards it into the api container
Parameters__SentryDsn: ${{ secrets.SENTRY_DSN }}
# VirusTotal API key — optional; enables live release scan badges on the download page
Parameters__VirusTotalApiKey: ${{ secrets.VIRUSTOTAL_API_KEY }}
# GitHub API token — raises the release-feed rate limit from 60/hr (shared IP) to 5,000/hr
Parameters__GitHubApiToken: ${{ secrets.GH_API_TOKEN }}
# Discord channel webhook — announces new challenges + solves (unset = disabled)
Parameters__DiscordWebhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }}
# WeChall site-connector shared secret — gates account-existence probing (unset = validate always returns "0")
Parameters__WeChallAuthKey: ${{ secrets.WECHALL_AUTH_KEY }}