Some checks failed
Dependency builds / Build web (pull_request) Has been skipped
Dependency builds / Build desktop (pull_request) Has been skipped
Dependency builds / Test native MTP (pull_request) Has been skipped
Dependency builds / Build mobile (pull_request) Has been skipped
/ build-web (push) Successful in 7m14s
/ build-mobile (push) Failing after 12m6s
/ build-desktop (linux) (push) Successful in 12m16s
/ release (push) Has been skipped
# Conflicts: # apps/pwa/src/runtime.tsx # flake.nix # packages/mtp/src/context.test.tsx # packages/mtp/src/context.tsx
368 lines
13 KiB
YAML
368 lines
13 KiB
YAML
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches:
|
|
- main
|
|
paths-ignore:
|
|
- flake.nix
|
|
|
|
jobs:
|
|
build-web:
|
|
runs-on: nixos
|
|
steps:
|
|
- name: Check out repo
|
|
uses: https://data.forgejo.org/actions/checkout@v4
|
|
|
|
- name: Pull git submodules
|
|
run: git submodule update --init --recursive
|
|
|
|
- name: Install dependencies
|
|
run: nix develop .#electron --command pnpm install --frozen-lockfile
|
|
|
|
- name: Copy licenses
|
|
run: nix develop .#electron --command pnpm run copy-licenses
|
|
|
|
- name: Build packages
|
|
run: nix develop .#electron --command pnpm run build:packages
|
|
|
|
- name: Build web
|
|
run: nix develop .#electron --command pnpm run build:web
|
|
|
|
- name: Deploy
|
|
run: nix develop .#electron --command rsync -a --delete apps/web/dist/ /var/lib/www/tensamin-web-prod/
|
|
|
|
build-mobile:
|
|
runs-on: nixos
|
|
steps:
|
|
- name: Check out repo
|
|
uses: https://data.forgejo.org/actions/checkout@v4
|
|
|
|
- name: Pull git submodules
|
|
run: git submodule update --init --recursive
|
|
|
|
- name: Install dependencies
|
|
run: nix develop .#tauri --command pnpm install --frozen-lockfile
|
|
|
|
- name: Copy licenses
|
|
run: nix develop .#tauri --command pnpm run copy-licenses
|
|
|
|
- name: Build packages
|
|
run: nix develop .#tauri --command pnpm run build:packages
|
|
|
|
- name: Setup Android Keystore
|
|
env:
|
|
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
|
KEYSTORE_PROPERTIES: ${{ secrets.ANDROID_KEYSTORE_PROPERTIES }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [ -z "$KEYSTORE_BASE64" ]; then
|
|
echo "ANDROID_KEYSTORE_BASE64 secret is missing or empty"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$KEYSTORE_PROPERTIES" ]; then
|
|
echo "ANDROID_KEYSTORE_PROPERTIES secret is missing or empty"
|
|
exit 1
|
|
fi
|
|
|
|
printf '%s' "$KEYSTORE_BASE64" \
|
|
| tr -d '[:space:]' \
|
|
| base64 -d > keystore.jks
|
|
|
|
printf '%s' "$KEYSTORE_PROPERTIES" \
|
|
| sed 's/\\n/\n/g' \
|
|
| tr -d '\r' \
|
|
| sed 's|^[[:space:]]*storeFile[[:space:]]*=.*|storeFile=keystore.jks|' \
|
|
> keystore.properties
|
|
|
|
grep -q '^[[:space:]]*storeFile[[:space:]]*=' keystore.properties || printf '\nstoreFile=keystore.jks\n' >> keystore.properties
|
|
|
|
if [ ! -s keystore.jks ]; then
|
|
echo "Decoded keystore.jks is missing or empty"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -s keystore.properties ]; then
|
|
echo "Generated keystore.properties is missing or empty"
|
|
exit 1
|
|
fi
|
|
|
|
if ! grep -q '^[[:space:]]*keyAlias[[:space:]]*=' keystore.properties; then
|
|
echo "keystore.properties is missing keyAlias"
|
|
exit 1
|
|
fi
|
|
|
|
if ! grep -Eq '^[[:space:]]*(keyPassword|password)[[:space:]]*=' keystore.properties; then
|
|
echo "keystore.properties is missing keyPassword or password"
|
|
exit 1
|
|
fi
|
|
|
|
if ! grep -Eq '^[[:space:]]*(storePassword|password)[[:space:]]*=' keystore.properties; then
|
|
echo "keystore.properties is missing storePassword or password"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Build mobile
|
|
run: nix develop .#tauri --command pnpm run build:mobile
|
|
|
|
- name: Upload mobile artifact
|
|
uses: https://data.forgejo.org/actions/upload-artifact@v3
|
|
with:
|
|
name: mobile-apk
|
|
path: apps/tauri/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk
|
|
|
|
build-desktop:
|
|
runs-on: nixos
|
|
strategy:
|
|
matrix:
|
|
target: [linux]
|
|
steps:
|
|
- name: Check out repo
|
|
uses: https://data.forgejo.org/actions/checkout@v4
|
|
|
|
- name: Pull git submodules
|
|
run: git submodule update --init --recursive
|
|
|
|
- name: Install dependencies
|
|
run: nix develop .#electron --command pnpm install --frozen-lockfile
|
|
|
|
- name: Copy licenses
|
|
run: nix develop .#electron --command pnpm run copy-licenses
|
|
|
|
- name: Build packages
|
|
run: nix develop .#electron --command pnpm run build:packages
|
|
|
|
- name: Set Electron prod version
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -euo pipefail
|
|
VERSION="$(node -p "require('./package.json').version")"
|
|
export VERSION
|
|
node -e '
|
|
const fs = require("fs");
|
|
const path = "apps/electron/package.json";
|
|
const pkg = JSON.parse(fs.readFileSync(path, "utf8"));
|
|
pkg.version = process.env.VERSION;
|
|
fs.writeFileSync(path, JSON.stringify(pkg, null, 2) + "\n");
|
|
'
|
|
EOF
|
|
|
|
- name: Build Electron desktop
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -euo pipefail
|
|
cd apps/electron
|
|
pnpm run package:raw
|
|
EOF
|
|
|
|
- name: Upload desktop artifacts
|
|
uses: https://data.forgejo.org/actions/upload-artifact@v3
|
|
with:
|
|
name: electron-desktop-${{ matrix.target }}
|
|
path: apps/electron/release/
|
|
|
|
release:
|
|
runs-on: nixos
|
|
needs: [build-web, build-mobile, build-desktop]
|
|
steps:
|
|
- name: Check out repo
|
|
uses: https://data.forgejo.org/actions/checkout@v4
|
|
|
|
- name: Pull git submodules
|
|
run: git submodule update --init --recursive
|
|
|
|
- name: Install dependencies
|
|
run: nix develop .#electron --command pnpm install --frozen-lockfile
|
|
|
|
- name: Download mobile artifact
|
|
uses: https://data.forgejo.org/actions/download-artifact@v3
|
|
with:
|
|
name: mobile-apk
|
|
path: apps/tauri/src-tauri/gen/android/app/build/outputs/apk/universal/release/
|
|
|
|
- name: Download desktop artifacts
|
|
uses: https://data.forgejo.org/actions/download-artifact@v3
|
|
with:
|
|
name: electron-desktop-linux
|
|
path: apps/electron/release/
|
|
|
|
- name: Read version
|
|
id: version
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -euo pipefail
|
|
VERSION="$(node -p "require('./package.json').version")"
|
|
echo "version=$VERSION" >> "$FORGEJO_OUTPUT"
|
|
echo "tag=$VERSION" >> "$FORGEJO_OUTPUT"
|
|
EOF
|
|
|
|
- name: Copy releases
|
|
env:
|
|
TENSAMIN_RELEASE_VERSION: ${{ steps.version.outputs.tag }}
|
|
TENSAMIN_RELEASE_TAG: ${{ steps.version.outputs.tag }}
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -euo pipefail
|
|
ASSET_BASE_URL="${{ forgejo.api_url }}"
|
|
ASSET_BASE_URL="${ASSET_BASE_URL%/api/v1}/${{ forgejo.repository }}/releases/download/${{ steps.version.outputs.tag }}"
|
|
FORGEJO_RELEASE_ASSET_BASE_URL="$ASSET_BASE_URL" pnpm run copy-releases
|
|
EOF
|
|
|
|
- name: Create release and upload files
|
|
env:
|
|
TOKEN: ${{ forgejo.token }}
|
|
API: ${{ forgejo.api_url }}
|
|
REPO: ${{ forgejo.repository }}
|
|
SHA: ${{ forgejo.sha }}
|
|
TAG: ${{ steps.version.outputs.tag }}
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -eu
|
|
|
|
test -d releases
|
|
find releases -type f | grep -q .
|
|
|
|
COMMIT_MSG="$(git log -1 --pretty=%B | sed 's/$/ /')"
|
|
|
|
HTTP_STATUS=$(curl -s -w "%{http_code}" -o release_out.json -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/tags/$TAG")
|
|
|
|
if [ "$HTTP_STATUS" = "200" ]; then
|
|
echo "Release $TAG already exists."
|
|
exit 0
|
|
fi
|
|
|
|
echo "Creating new release for $TAG"
|
|
RELEASE_JSON="$(curl -f -sS -X POST "$API/repos/$REPO/releases" \
|
|
-H "Authorization: token $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$(jq -n \
|
|
--arg tag "$TAG" \
|
|
--arg name "$TAG" \
|
|
--arg body "$COMMIT_MSG" \
|
|
--arg target "$SHA" \
|
|
'{
|
|
tag_name: $tag,
|
|
name: $name,
|
|
body: $body,
|
|
target_commitish: $target,
|
|
draft: false,
|
|
prerelease: false
|
|
}')")"
|
|
RELEASE_ID="$(echo "$RELEASE_JSON" | jq -r .id)"
|
|
|
|
ASSET_BASE_URL="${API%/api/v1}/$REPO/releases/download/$TAG"
|
|
export ASSET_BASE_URL
|
|
node -e '
|
|
const fs = require("fs");
|
|
const path = "releases/electron-release-metadata.json";
|
|
const metadata = JSON.parse(fs.readFileSync(path, "utf8"));
|
|
metadata.version = process.env.TAG;
|
|
metadata.tag = process.env.TAG;
|
|
for (const artifact of metadata.artifacts || []) {
|
|
artifact.url = `${process.env.ASSET_BASE_URL}/${encodeURIComponent(artifact.name)}`;
|
|
}
|
|
fs.writeFileSync(path, `${JSON.stringify(metadata, null, 2)}\n`);
|
|
'
|
|
|
|
find releases -type f -print0 | while IFS= read -r -d '' file; do
|
|
name="$(basename "$file")"
|
|
curl -fsS -X POST "$API/repos/$REPO/releases/$RELEASE_ID/assets?name=$name" \
|
|
-H "Authorization: token $TOKEN" \
|
|
-F "attachment=@$file"
|
|
done
|
|
EOF
|
|
|
|
- name: Delete dev releases
|
|
env:
|
|
TOKEN: ${{ forgejo.token }}
|
|
API: ${{ forgejo.api_url }}
|
|
REPO: ${{ forgejo.repository }}
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -eu
|
|
|
|
PAGE=1
|
|
DELETE_RELEASES=delete-dev-releases.tsv
|
|
|
|
: > "$DELETE_RELEASES"
|
|
|
|
while :; do
|
|
curl -fsS \
|
|
-H "Authorization: token $TOKEN" \
|
|
"$API/repos/$REPO/releases?page=$PAGE&limit=50&pre-release=true" \
|
|
-o releases.json
|
|
|
|
COUNT="$(jq 'length' releases.json)"
|
|
test "$COUNT" -gt 0 || break
|
|
|
|
jq -r \
|
|
'.[] | select(.prerelease == true) | select(.tag_name | contains("-dev-")) | [.id, .tag_name] | @tsv' releases.json \
|
|
>> "$DELETE_RELEASES"
|
|
|
|
PAGE="$((PAGE + 1))"
|
|
done
|
|
|
|
while IFS="$(printf '\t')" read -r release_id release_tag; do
|
|
test -n "$release_id" || continue
|
|
echo "Deleting dev release $release_tag"
|
|
curl -fsS -X DELETE \
|
|
-H "Authorization: token $TOKEN" \
|
|
"$API/repos/$REPO/releases/$release_id"
|
|
done < "$DELETE_RELEASES"
|
|
EOF
|
|
|
|
- name: Update root flake release hash
|
|
env:
|
|
TAG: ${{ steps.version.outputs.tag }}
|
|
run: |
|
|
nix develop .#electron --command bash <<'EOF'
|
|
set -eu
|
|
|
|
DEB="$(find releases -maxdepth 1 -type f -name 'Tensamin-*-linux-amd64.deb' -print -quit)"
|
|
test -n "$DEB"
|
|
|
|
HASH="$(node -e 'const fs = require("fs"); const crypto = require("crypto"); const file = process.argv[1]; console.log("sha256-" + crypto.createHash("sha256").update(fs.readFileSync(file)).digest("base64"));' "$DEB")"
|
|
export HASH
|
|
|
|
node -e '
|
|
const fs = require("fs");
|
|
const version = process.env.TAG;
|
|
const hash = process.env.HASH;
|
|
let content = fs.readFileSync("flake.nix", "utf8");
|
|
content = content.replace(/version = "[^"]+";/, `version = "${version}";`);
|
|
content = content.replace(/x86_64DebHash = "sha256-[^"]+";/, `x86_64DebHash = "${hash}";`);
|
|
fs.writeFileSync("flake.nix", content);
|
|
'
|
|
|
|
if git diff --quiet -- flake.nix; then
|
|
echo "flake.nix already has the current release hash on main."
|
|
else
|
|
git add flake.nix
|
|
git -c user.name="forgejo-actions" -c user.email="forgejo-actions@localhost" commit -m "(qol): update release flake hash"
|
|
git push
|
|
fi
|
|
|
|
git fetch origin dev
|
|
git worktree add ../dev-flake-update origin/dev
|
|
cd ../dev-flake-update
|
|
|
|
node -e '
|
|
const fs = require("fs");
|
|
const version = process.env.TAG;
|
|
const hash = process.env.HASH;
|
|
let content = fs.readFileSync("flake.nix", "utf8");
|
|
content = content.replace(/version = "[^"]+";/, `version = "${version}";`);
|
|
content = content.replace(/x86_64DebHash = "sha256-[^"]+";/, `x86_64DebHash = "${hash}";`);
|
|
fs.writeFileSync("flake.nix", content);
|
|
'
|
|
|
|
if git diff --quiet -- flake.nix; then
|
|
echo "flake.nix already has the current release hash on dev."
|
|
exit 0
|
|
fi
|
|
|
|
git add flake.nix
|
|
git -c user.name="forgejo-actions" -c user.email="forgejo-actions@localhost" commit -m "(qol): update release flake hash"
|
|
git push origin HEAD:dev
|
|
EOF
|