diff --git a/.forgejo/workflows/build.yaml b/.forgejo/workflows/build.yaml deleted file mode 100644 index 3a8cfa3..0000000 --- a/.forgejo/workflows/build.yaml +++ /dev/null @@ -1,71 +0,0 @@ -name: Test build - -on: - push: - tags-ignore: - - "*" - branches-ignore: - - master - - ci - -jobs: - build: - runs-on: ubuntu - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules - git submodule update --init - - name: Check commit - id: check - run: | - git fetch && git checkout master - sha=$(git rev-parse HEAD) - [[ "${{ github.sha }}" == "${sha}" ]] && test=false || test=true - echo "test=${test}" >> "$FORGEJO_OUTPUT" - - name: Restore cargo cache - id: cache-cargo-restore - uses: actions/cache/restore@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-test-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Setup registry - run: | - echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml - - name: Build - if: ${{ steps.check.outputs.test == 'true' }} - run: cargo build --release - - name: Save cargo cache - uses: actions/cache/save@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }} - - name: Telegram Notify Channel - if: ${{ steps.check.outputs.test == 'true' && (success() || failure()) }} - uses: actions/telegram-notifier@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - chat_id: ${{ secrets.TELEGRAM_CHANNEL_ID }} - status: ${{ job.status }} - notify_fields: "actor,repository,workflow,branch,commit" - - name: Telegram Notify Group - if: ${{ steps.check.outputs.test == 'true' && (success() || failure()) }} - uses: actions/telegram-notifier@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - chat_id: ${{ secrets.TELEGRAM_GROUP_ID }} - status: ${{ job.status }} - notify_fields: "actor,repository,workflow,branch,commit" \ No newline at end of file diff --git a/.forgejo/workflows/pr.yaml b/.forgejo/workflows/pr.yaml deleted file mode 100644 index fbc5dcb..0000000 --- a/.forgejo/workflows/pr.yaml +++ /dev/null @@ -1,29 +0,0 @@ -name: Pull Request - -on: - pull_request: - types: - - closed - - opened - -jobs: - notify: - runs-on: debian-release - - steps: - - name: Telegram Notify Channel - uses: actions/telegram-notifier@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - chat_id: ${{ secrets.TELEGRAM_CHANNEL_ID }} - status: ${{ job.status }} - notify_fields: "actor,repository" - - name: Telegram Notify Group - uses: actions/telegram-notifier@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - chat_id: ${{ secrets.TELEGRAM_GROUP_ID }} - status: ${{ job.status }} - notify_fields: "actor,repository" \ No newline at end of file diff --git a/.forgejo/workflows/release.yaml b/.forgejo/workflows/release.yaml deleted file mode 100644 index 1950378..0000000 --- a/.forgejo/workflows/release.yaml +++ /dev/null @@ -1,474 +0,0 @@ -name: Release build - -on: - push: - branches: - - master - - ci - tags-ignore: - - "*-dev*" - -jobs: - version: - runs-on: debian-release - outputs: - v: ${{ steps.version.outputs.v }} - pre: ${{ steps.version.outputs.pre }} - exists: ${{ steps.check.outputs.exists }} - last_tag: ${{ steps.check_prev.outputs.last_tag }} - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules - git submodule update --init - - name: Get version - id: version - run: | - ver="$(grep -m 1 -Po 'version = "\K[^"]*' Cargo.toml)" - [[ $ver == *"-dev"* ]] && ver=${ver} || ver=${ver}-dev - [[ ${{ forgejo.ref_type }} == 'tag' ]] && app_ver=${{ forgejo.ref_name }} || app_ver=v${ver} - echo "v=${app_ver}" >> "$FORGEJO_OUTPUT" - echo $app_ver - [[ ${{ forgejo.ref_type }} == 'tag' ]] && pre='false' || pre='true' - echo "pre=${pre}" >> "$FORGEJO_OUTPUT" - echo "pre-release: ${pre}" - - name: Check existing release - if: ${{ forgejo.ref_type == 'tag' }} - id: check - run: | - git fetch --tags - dev_sha=$(git rev-parse refs/tags/${{ forgejo.ref_name }}-dev) || : - [[ "$(git show-ref)" == *"${dev_sha}"* ]] && exists='true' || exists='false' - echo "exists=${exists}" >> "$FORGEJO_OUTPUT" - echo ${exists} - mkdir release - - uses: actions/forgejo-release@v2.11.3 - if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }} - with: - direction: download - token: ${{ secrets.RELEASE_TOKEN }} - tag: "${{ forgejo.ref_name }}-dev" - release-dir: ./release - - name: Rename files - if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }} - working-directory: release - run: for f in *; do mv "$f" "$(echo "$f" | sed s/-dev-/-/)"; done - - name: Delete dev release - if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }} - uses: actions/delete-release@v1 - with: - release_name: "${{ forgejo.ref_name }}-dev" - - name: Check previous release - id: check_prev - run: | - git fetch --tags - [[ ${{ forgejo.ref_type }} == 'tag' ]] && skip=0 || skip=1 - last_tag=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=${skip} --max-count=1)) || true - echo "last_tag=${last_tag}" >> "$FORGEJO_OUTPUT" - - uses: actions/forgejo-release@v2.11.3 - if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }} - with: - direction: upload - token: ${{ secrets.RELEASE_TOKEN }} - tag: ${{ forgejo.ref_name }} - override: false - prerelease: false - release-dir: ./release - release-notes: "Full Changelog: [${{ steps.check_prev.outputs.last_tag }}...${{ steps.version.outputs.v }}](https://code.gri.mw/${{ forgejo.repository }}/compare/${{ steps.check_prev.outputs.last_tag }}...${{ steps.version.outputs.v }})" - - android: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: macos - needs: version - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - sed -i -- 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules - git submodule update --init - - name: Restore cargo cache - id: cache-cargo-restore - uses: actions/cache/restore@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: goblin-android-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Build libs - run: | - rustup -q update - chmod +x scripts/android.sh && ./scripts/android.sh lib ${{ needs.version.outputs.v }} - - name: Save cargo cache - uses: actions/cache/save@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }} - - name: Restore gradle cache - id: cache-gradle-restore - uses: actions/cache/restore@v5 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: goblin-android-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Setup build - run: | - chmod +x android/gradlew - echo "${{ secrets.ANDROID_KEYSTORE }}" > release.keystore.txt - base64 -d < release.keystore.txt -o android/keystore - echo "${{ secrets.ANDROID_KEYSTORE_PROPS }}" > release.keystore.props.txt - base64 -d < release.keystore.props.txt -o android/keystore.properties - mkdir ~/.gradle && touch ~/.gradle/gradle.properties - printf "mavenHost=${{ secrets.MAVEN_LOCAL_HOST }}\n" >> ~/.gradle/gradle.properties - printf "mavenUser=${{ secrets.MAVEN_USER }}\n" >> ~/.gradle/gradle.properties - printf "mavenPassword=${{ secrets.MAVEN_PASSWORD }}" >> ~/.gradle/gradle.properties - - name: Release ARMv7+v8 APK - working-directory: android - run: | - jni_path=app/src/main/jniLibs - mv ${jni_path}/x86_64 x86_64 - ./gradlew assembleCiSignedRelease - apk_path=app/build/outputs/apk/ci/signedRelease/app-ci-signedRelease.apk - name=goblin-${{ needs.version.outputs.v }}-android.apk - mv ${apk_path} "${name}" - - name: Checksum ARM APK - working-directory: android - run: | - name=goblin-${{ needs.version.outputs.v }}-android.apk - checksum=goblin-${{ needs.version.outputs.v }}-android-sha256sum.txt - sha256sum "${name}" > "${checksum}" - - name: Release x86_64 APK - working-directory: android - run: | - ./gradlew clean - jni_path=app/src/main/jniLibs - rm -rf ${jni_path}/* - mv x86_64 ${jni_path} - ./gradlew assembleCiSignedRelease - apk_path=app/build/outputs/apk/ci/signedRelease/app-ci-signedRelease.apk - name=goblin-${{ needs.version.outputs.v }}-android-x86_64.apk - mv ${apk_path} "${name}" - - name: Save gradle cache - uses: actions/cache/save@v5 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ steps.cache-gradle-restore.outputs.cache-primary-key }} - - name: Checksum x86_64 APK - working-directory: android - run: | - name=goblin-${{ needs.version.outputs.v }}-android.apk - checksum=goblin-${{ needs.version.outputs.v }}-android-x86_64-sha256sum.txt - sha256sum "${name}" > "${checksum}" - - name: Upload artifacts - run: | - mkdir release - mv android/goblin* release - tar -czf android.tar.gz release - curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file android.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/android.tar.gz - - linux_arm: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: debian-rust-arm - needs: [version] - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules - git submodule update --init - - name: Restore cargo cache - id: cache-cargo-restore - uses: actions/cache/restore@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: goblin-linux-arm-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Setup registry - run: | - echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"' > ~/.cargo/config.toml - - name: Release Linux ARM - run: | - rustup -q update - cargo zigbuild --release --target aarch64-unknown-linux-gnu - - name: Save cargo cache - uses: actions/cache/save@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }} - - name: Upload artifacts - run: | - curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file target/aarch64-unknown-linux-gnu/release/goblin ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/goblin-linux-arm - - linux_arm_appimage: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: debian-arm - needs: [version, linux_arm] - steps: - - uses: actions/checkout@v6 - - name: Download Artifact - run: | - wget ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/goblin-linux-arm - - name: AppImage - shell: bash - run: | - mkdir release - chmod +x goblin-linux-arm - mv goblin-linux-arm linux/Goblin.AppDir/AppRun - ARCH=aarch64 appimagetool linux/Goblin.AppDir goblin-${{ needs.version.outputs.v }}-linux-arm.AppImage - mv goblin-${{ needs.version.outputs.v }}-linux-arm.AppImage release/ - - name: Checksum AppImage ARM - working-directory: release - run: sha256sum goblin-${{ needs.version.outputs.v }}-linux-arm.AppImage > goblin-${{ needs.version.outputs.v }}-linux-arm-appimage-sha256sum.txt - - name: Upload artifacts - run: | - tar -czf linux-arm.appimage.tar.gz release - curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-arm.appimage.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/linux-arm.appimage.tar.gz - - linux_x86: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: debian-rust-x86_64 - needs: [version] - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules - git submodule update --init - - name: Restore cargo cache - id: cache-cargo-restore - uses: actions/cache/restore@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: goblin-linux-arm-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Setup registry - run: | - echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"' > ~/.cargo/config.toml - - name: Release Linux x86 - run: | - rustup -q update - cargo zigbuild --release --target x86_64-unknown-linux-gnu - - name: Save cargo cache - uses: actions/cache/save@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }} - - name: AppImage x86 - run: | - mkdir release - mv target/x86_64-unknown-linux-gnu/release/goblin linux/Goblin.AppDir/AppRun - appimagetool linux/Goblin.AppDir goblin-${{ needs.version.outputs.v }}-linux-x86_64.AppImage - mv goblin-${{ needs.version.outputs.v }}-linux-x86_64.AppImage release/ - - name: Checksum AppImage x86 - working-directory: release - run: sha256sum goblin-${{ needs.version.outputs.v }}-linux-x86_64.AppImage > goblin-${{ needs.version.outputs.v }}-linux-x86_64-appimage-sha256sum.txt - - name: Upload artifacts - run: | - tar -czf linux-x86_64.appimage.tar.gz release - curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-x86_64.appimage.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/linux-x86_64.appimage.tar.gz - - macos: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: macos - needs: [version, android] - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - sed -i -- 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules - git submodule update --init - - run: mkdir release - - name: Restore cargo cache - id: cache-cargo-restore - uses: actions/cache/restore@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: goblin-macos-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Release MacOS Universal - run: | - rustup -q update - export MACOSX_DEPLOYMENT_TARGET=11.0 - cargo build --release --target x86_64-apple-darwin - cargo build --release --target aarch64-apple-darwin - lipo -create -output goblin "target/x86_64-apple-darwin/release/goblin" "target/aarch64-apple-darwin/release/goblin" - mv goblin macos/Goblin.app/Contents/MacOS - - name: Save cargo cache - uses: actions/cache/save@v5 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }} - - name: Archive Universal - working-directory: macos - run: | - zip -r goblin-${{ needs.version.outputs.v }}-macos-universal.zip Goblin.app - mv goblin-${{ needs.version.outputs.v }}-macos-universal.zip ../release - - name: Checksum Release Universal - working-directory: release - run: sha256sum goblin-${{ needs.version.outputs.v }}-macos-universal.zip > goblin-${{ needs.version.outputs.v }}-macos-universal-sha256sum.txt - - name: Upload artifacts - run: | - tar -czf macos.tar.gz release - curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file macos.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/macos.tar.gz - - windows: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: windows - needs: [version] - steps: - - uses: actions/checkout@v6 - - name: Checkout submodules - run: | - (Get-content .gitmodules) | Foreach-Object {$_ -replace "https://code.gri.mw", "${{ secrets.REPO_HOST }}"} | Set-Content .gitmodules - git submodule update --init - - name: Update UpgradeCode - shell: powershell - run: | - $guid = [guid]::NewGuid().ToString() - $wix = [xml](Get-Content wix/main.wxs) - $wix.Wix.Product.UpgradeCode = $guid - $wix.Save("wix/main.wxs") - Get-Content wix/main.wxs - - run: mkdir release - - name: Release Windows x86 - run: | - rustup -q update - cargo wix -p goblin -o goblin-${{ needs.version.outputs.v }}-win-x86_64.msi --nocapture - mv goblin-${{ needs.version.outputs.v }}-win-x86_64.msi release\ - Compress-Archive -Path target\release\goblin.exe -DestinationPath goblin-${{ needs.version.outputs.v }}-win-x86_64.zip - mv goblin-${{ needs.version.outputs.v }}-win-x86_64.zip release\ - - name: Checksum Archive x86 - working-directory: release - run: | - certutil -hashfile goblin-${{ needs.version.outputs.v }}-win-x86_64.msi SHA256 > goblin-${{ needs.version.outputs.v }}-win-x86_64-msi-sha256sum.txt - certutil -hashfile goblin-${{ needs.version.outputs.v }}-win-x86_64.zip SHA256 > goblin-${{ needs.version.outputs.v }}-win-x86_64-sha256sum.txt - - name: Upload artifacts - run: | - tar -czf windows.tar.gz release - Remove-Item alias:curl - curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file windows.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/windows.tar.gz - - release: - if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }} - runs-on: debian-release - needs: [version, android, linux_x86, linux_arm_appimage, macos, windows] - steps: - - name: Download All Artifacts - run: | - curl -s -o android.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/android.tar.gz - tar -xzf android.tar.gz - rm android.tar.gz - curl -s -o linux-x86_64.appimage.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/linux-x86_64.appimage.tar.gz - tar -xzf linux-x86_64.appimage.tar.gz - rm linux-x86_64.appimage.tar.gz - curl -s -o linux-arm.appimage.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/linux-arm.appimage.tar.gz - tar -xzf linux-arm.appimage.tar.gz - rm linux-arm.appimage.tar.gz - curl -s -o macos.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/macos.tar.gz - tar -xzf macos.tar.gz - rm macos.tar.gz - curl -s -o windows.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/goblin-ci/${{ forgejo.repository }}/windows.tar.gz - tar -xzf windows.tar.gz - rm windows.tar.gz - - name: Upload release to Forgejo - uses: actions/forgejo-release@v2.11.3 - with: - direction: upload - token: ${{ secrets.RELEASE_TOKEN }} - tag: ${{ needs.version.outputs.v }} - override: true - prerelease: ${{ needs.version.outputs.pre == 'true' }} - release-dir: release - release-notes: "Full Changelog: [${{ needs.version.outputs.last_tag }}...${{ needs.version.outputs.v }}](https://code.gri.mw/${{ forgejo.repository }}/compare/${{ needs.version.outputs.last_tag }}...${{ needs.version.outputs.v }})" - - name: Telegram Notify Channel - if: always() - uses: actions/telegram-notifier@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - chat_id: ${{ secrets.TELEGRAM_CHANNEL_ID }} - status: ${{ job.status }} - notify_fields: "actor,repository,workflow,branch,commit" - - name: Telegram Notify Group - if: always() - uses: actions/telegram-notifier@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - chat_id: ${{ secrets.TELEGRAM_GROUP_ID }} - status: ${{ job.status }} - notify_fields: "actor,repository,workflow,branch,commit" - - release-telegram: - runs-on: debian-release - needs: [version, release] - steps: - - name: Download All Artifacts - run: | - mkdir release - cd release - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-android.apk - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-android-x86_64.apk - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-linux-arm.AppImage - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-linux-x86_64.AppImage - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-macos-universal.zip - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-win-x86_64.msi - wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/goblin-${{ needs.version.outputs.v }}-win-x86_64.zip - - name: Upload files to Telegram - uses: actions/telegram-send-file@main - with: - api_url: ${{ secrets.TELEGRAM_API_URL }} - chat_ids: | - ${{ secrets.TELEGRAM_CHANNEL_ID }} - ${{ secrets.TELEGRAM_GROUP_ID }} - body: '🎁 Release ${{ needs.version.outputs.v }} is ready!' - token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - pin: true - files: | - release/goblin-${{ needs.version.outputs.v }}-android.apk - release/goblin-${{ needs.version.outputs.v }}-android-x86_64.apk - release/goblin-${{ needs.version.outputs.v }}-linux-arm.AppImage - release/goblin-${{ needs.version.outputs.v }}-linux-x86_64.AppImage - release/goblin-${{ needs.version.outputs.v }}-macos-universal.zip - release/goblin-${{ needs.version.outputs.v }}-win-x86_64.msi - release/goblin-${{ needs.version.outputs.v }}-win-x86_64.zip \ No newline at end of file diff --git a/DEVELOPING.md b/DEVELOPING.md deleted file mode 100644 index d515f5a..0000000 --- a/DEVELOPING.md +++ /dev/null @@ -1,206 +0,0 @@ -# Developing & testing Goblin - -How this fork is actually iterated on, built, driven, and verified β€” so you can -pick development back up after a `/clear` without re-deriving the loop. This is -the *dev/test workflow*, not an architecture tour (for that see `HANDOFF.md`, -the `~/.claude/.../memory/` notes, and the code map in -`goblin-implementation-state`). - -> **Secrets stay out of this file.** Test-wallet seed phrases and passwords are -> never committed. They live in the local handoff notes only. This doc refers -> to wallets by role. - ---- - -## 1. Workspace layout - -Everything lives under `…/Goblin Project/`: - -| Dir | What it is | -| --- | --- | -| `goblin/` | **The fork you edit.** Crate name `grim`, binary `goblin`. | -| `goblin-nip05d/` | The NIP-05 identity server (axum + sqlite), deployed at goblin.st. | -| `grim/`, `grin/`, `egui/`, `android-activity/`, `nokhwa/` | Reference clones β€” **not build inputs**, just there to read upstream source. | - -Inside `goblin/src/gui/views/`: -- `goblin/` β€” the Cash App-style surfaces (home/activity/send/receive/me, onboarding, the Goblin settings pages, widgets). -- `wallets/` β€” the wallet list + open-wallet host (returning-user list lives in `wallets/content.rs`). -- `network/` β€” the integrated GRIN node panel (stats/mining/tuning/recovery). -- `settings/` β€” the app-level cog settings (`settings/content.rs`). - -First build needs submodules: `git submodule update --init --recursive` inside -`goblin/` (else `grin_api` fails). As **butler**, the rustup toolchain is in -`$HOME`, so `cargo`/`rustc`/`rustfmt` just work β€” no env overrides. - ---- - -## 2. Build & versioning - -```sh -cd goblin -cargo build # ~15s incremental debug; clean release ~2m -``` - -**Builds are numbered, not semver'd.** `build.rs` computes -`Build N = git rev-list --count b51a46b..HEAD` (the GRIM fork base) and exposes -it as the `GOBLIN_BUILD` env var baked into the binary. Each meaningful change -is committed with the message `Build N`. To see the next number: - -```sh -git rev-list --count b51a46b..HEAD -``` - -A pre-commit hook runs `rustfmt --check` and aborts if anything is unformatted -(it reformats first). Always run `rustfmt --edition 2024 ` -before committing. Pushing `origin master` is the owner's job. - ---- - -## 3. Driving the real app for screenshots (Xwayland :2) - -The desktop session is **KDE Wayland**, where `xdotool` input injection does -**not** work (and Parsec may hold the live display). The validated recipe is a -throwaway rootful Xwayland server on display `:2`: - -```sh -# 1. Stand up an isolated X server (once per session; no window manager inside). -Xwayland :2 -geometry 1600x1000 -decorate -noreset & - -# 2. Launch Goblin onto it. MUST unset WAYLAND_DISPLAY or winit picks Wayland. -env -u WAYLAND_DISPLAY DISPLAY=:2 ./target/debug/goblin & - -# 3. Find the window, focus it (no WM => keys go nowhere until you focus once). -WID=$(DISPLAY=:2 xdotool search --name Goblin | head -1) -DISPLAY=:2 xdotool windowfocus "$WID" - -# 4. Drive it. -DISPLAY=:2 xdotool mousemove click 1 -DISPLAY=:2 xdotool type 'hello' -DISPLAY=:2 xdotool key Return - -# 5. Capture (ImageMagick). No WM => window sits at 0,0, so image coords == click coords. -DISPLAY=:2 import -window "$WID" /tmp/shot.png -``` - -Form factors β€” resize the window to test responsive layouts: - -```sh -DISPLAY=:2 xdotool windowsize "$WID" 390 844 # mobile (bottom tabs) -DISPLAY=:2 xdotool windowsize "$WID" 1280 800 # desktop sidebar (>=720px wide) -``` - -The layout flips between mobile bottom-tabs and desktop sidebar around 700-720px. - -Kill stale instances by exact name only β€” **`pgrep -x goblin`, never `-f`** -(`-f` would match this checkout's paths and your editor). Data dir is `~/.goblin`. - ---- - -## 4. The `goblin-gui-sweep` workflow (run after every UI change) - -The saved multi-agent workflow at `.claude/workflows/goblin-gui-sweep.js` -(project root) is the standard post-UI-change check. Invoke it via the Workflow -tool by name `goblin-gui-sweep`. It: - -1. **Capture** β€” stands up `:2` if dead, builds, kills stale instances, launches, - unlocks the test wallet, and drives **every** surface (desktop + mobile - widths, all three themes, settings sub-pages, a send-to-review via a local - npub, the ~700px responsive flip), screenshotting to `/tmp/goblin-gui-sweep/`. -2. **Review** β€” fans out reviewer agents (rendering / accessibility / design / - copy) over the screenshot groups. -3. **Verify** β€” adversarially re-checks each finding to drop false positives. -4. **Report** β€” writes `/tmp/goblin-gui-sweep/report.md` + `collage.png`. - -The driver always finishes its rotation (it restores the Dark theme and locks -back), and known-normal states are allowlisted in the reviewer prompts so they -aren't re-flagged. - -> Immediate-mode caveat: egui lags one frame on click, so a nav highlight may be -> missing in the exact frame you clicked. Verify highlights on the *next* -> capture, not the click frame β€” several "bugs" have been this artifact. - ---- - -## 5. Test wallets - -Live testing uses real GRIN on mainnet, so there are dedicated wallets: - -- A **local dev wallet** in `~/.goblin` for GUI drives (used by the sweep). -- **Two funded mainnet wallets** imported for end-to-end send/receive β€” referred - to by role: **Wallet A** and **Wallet B (`@fartmuncher22`)**. Wallet B holds a - small amount of grin for full live payment tests. - -**Their seed phrases and passwords are deliberately kept out of the repo** β€” see -the local handoff notes. Never paste them into code, logs, commits, or galleries. - ---- - -## 6. Identity / relay / node infra - -The live backend runs on **`us-ea.st`** (`ssh us-east`): - -- **Relay** β€” `wss://nrelay.us-ea.st` (the Goblin relay, docker). The relay we - control; always keep it in the relay set for deliverability. -- **NIP-05 server** β€” `goblin-nip05d` (axum + sqlite) at `/opt/goblin/nip05d`, - serving `https://goblin.st` (registration, avatars, `.well-known/nostr.json`). -- **DNS** β€” PowerDNS; **nginx** fronts goblin.st and hosts the `/review` gallery. -- **GRIN node** β€” mainnet node at `127.0.0.1:3413`. - -Payments are NIP-17 gift wraps (kind 1059). `DEFAULT_RELAYS` (`src/nostr/relays.rs`) -is `nrelay.us-ea.st` + `relay.damus.io` + `nos.lol`; the recipient's kind-10050 -DM-relay list plus the sender's own relays decide where a payment is delivered, -so **both parties must share at least one reachable relay**. The relay set is -user-editable in **Goblin β†’ Settings β†’ Relays** (`gui/views/goblin/mod.rs`, -`relays_ui`); Save & reconnect rewrites kind-10050 and restarts the service. - ---- - -## 7. Tests - -```sh -cd goblin -cargo test --lib # fast unit tests, offline - -# Live network e2e (opt-in, hit real relays/server) β€” tests/nostr_e2e.rs: -cargo test --test nostr_e2e nip17_slatepack_roundtrip -- --ignored --nocapture # our relay -cargo test --test nostr_e2e nip17_roundtrip -- --ignored --nocapture # + damus.io + nos.lol -cargo test --test nostr_e2e nip05_registration -- --ignored --nocapture # goblin.st register/resolve -cargo test --test nostr_e2e avatar -- --ignored --nocapture # avatar upload/serve/limit -cargo test --test replay_check -- --ignored --nocapture # server replay/squat guards -``` - -The `nip17_roundtrip_*` tests prove a gift-wrapped Goblin payment actually -transits each relay: Bob advertises a kind-10050 DM relay and subscribes; Alice -sends; Bob unwraps, checks the seal author, and extracts the slatepack. The -`--ignored` roundtrips can transiently time out on public-relay latency β€” re-run -before treating a timeout as a regression. - ---- - -## 8. Review galleries (goblin.st/review) - -Screenshot galleries from a sweep are published for the owner by copying the -collage/shots to `us-ea.st` under the nginx `/review/` location (note the -trailing slash β€” bare `/review` is 301'd to `/review/`). Galleries are put up -time-boxed (e.g. a 1- or 24-hour expiry) and taken down after. - ---- - -## 9. Gotchas worth keeping - -- **`View::title_button_big` paints dark-on-yellow ink** β€” invisible on a dark - surface. When you need an icon button on a dark background (e.g. the wallet-list - gear), draw it manually with `ui.painter().text(... Colors::text(false))`. -- **`xdotool` onboarding drives desync** when the layout shifts mid-flow (the - password-match step re-flows). Fresh-launch clean fields are reliable; the - word-confirm steps drift β€” don't trust a blind coordinate script across a - re-flow, re-screenshot and re-find. -- **Camera/QR:** open the device by `devices[pos].index()`, not the nostr - list-position β€” they differ and the wrong one opens the wrong `/dev/video*`. -- **Tor needs Go at build time.** `build.rs` builds the webtunnel bridge via - `scripts/webtunnel.sh`, which silently no-ops if Go is missing, embedding a - 0-byte bridge β†’ Tor never bootstraps. If relay/NIP-05 stay "connecting…": - `pacman -S go`, force a `build.rs` rerun (touch `build.rs`), rebuild. -- **`git` "dubious ownership"** after a prior root session: - `git config --global --add safe.directory "$PWD"`; root-owned `target/` - artifacts β†’ `sudo chown -R butler:butler goblin/target` or `cargo clean`.