diff --git a/.gitea/workflows/azure-pipelines.yml b/.gitea/workflows/azure-pipelines.yml new file mode 100644 index 0000000..61edb67 --- /dev/null +++ b/.gitea/workflows/azure-pipelines.yml @@ -0,0 +1,71 @@ +# Azure Pipelines — React Native (JS CI) +# https://learn.microsoft.com/azure/devops/pipelines/yaml-schema +# +# Same self-hosted pool as other repos — if this pipeline stays Queued or ignores your agent: +# 1) Pipelines → this pipeline → Edit → ⋯ → Triggers → YAML file path must be THIS file +# (repo root: /azure-pipelines.yml). +# 2) Project Settings → Agent pools → PerformicsCICD → Security → grant this pipeline access +# (or enable "Grant access permission to all pipelines"). +# +# Run on every push directly to main (and when merging into main via PR). +name: PerformicsDevOps-$(Date:yyyyMMdd)$(Rev:.r) + +trigger: + branches: + include: + - main + +pr: + branches: + include: + - main + +variables: + NODE_VERSION: '22.x' + +jobs: + - job: BuildAndTest + displayName: Performics DevOps Pipeline + # Self-hosted pool "PerformicsCICD" (same pattern as working Deeplink/azure-pipelines.yml). + pool: + name: PerformicsCICD + steps: + - checkout: self + displayName: Checkout + continueOnError: false + + - task: NodeTool@0 + displayName: Use Node.js + continueOnError: false + inputs: + versionSpec: $(NODE_VERSION) + + - script: | + set -euo pipefail + node -v + npm -v + pwd + displayName: Diagnostics + continueOnError: false + + - script: | + set -euo pipefail + npm ci + displayName: npm ci + continueOnError: false + + # - script: | + # set -euo pipefail + # npm run lint + # displayName: ESLint + # continueOnError: false + + - script: | + set -euo pipefail + cd android + ./gradlew assembleRelease + displayName: Android assembleRelease + continueOnError: false + + # - script: npm test -- --ci --coverage + # displayName: Jest diff --git a/scripts/setup-gitea-act-runner-ubuntu.sh b/scripts/setup-gitea-act-runner-ubuntu.sh new file mode 100644 index 0000000..c8fd6e9 --- /dev/null +++ b/scripts/setup-gitea-act-runner-ubuntu.sh @@ -0,0 +1,224 @@ +#!/usr/bin/env bash +# +# Install and register Gitea Actions act_runner on Ubuntu 20.04+ (x86_64 / arm64). +# See: https://docs.gitea.com/usage/actions/act-runner/ +# +# Prereq: Gitea with [actions] enabled; registration token from +# Site: Admin → Actions → Runners (or org/repo → Settings → Actions → Runners) +# +# Non-interactive (typical for automation): +# GITEA_INSTANCE_URL=https://gitea.example.com/ GITEA_RUNNER_REGISTRATION_TOKEN=xxxxx \ +# sudo -E bash scripts/setup-gitea-act-runner-ubuntu.sh +# +# Interactive registration (omit env vars; you will be prompted if register step runs as act_runner): +# sudo bash scripts/setup-gitea-act-runner-ubuntu.sh +# +# Optional: +# ACT_RUNNER_VERSION=0.2.13 # default: latest release from gitea.com API +# GITEA_RUNNER_NAME=my-runner +# GITEA_RUNNER_LABELS='ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04' +# --skip-docker # do not install Docker; use only if you use :host labels +# --no-systemd # install binary + config only, no service +# --skip-apt # skip apt update/install (you installed deps already) +# +set -euo pipefail + +ACT_RUNNER_USER="act_runner" +ACT_RUNNER_HOME="/var/lib/${ACT_RUNNER_USER}" +ACT_RUNNER_CONFIG="/etc/act_runner/config.yaml" +ACT_RUNNER_BIN="/usr/local/bin/act_runner" + +INSTALL_DOCKER=1 +INSTALL_SYSTEMD=1 +SKIP_APT=0 + +GITEA_INSTANCE_URL="${GITEA_INSTANCE_URL:-}" +GITEA_RUNNER_REGISTRATION_TOKEN="${GITEA_RUNNER_REGISTRATION_TOKEN:-}" +GITEA_RUNNER_NAME="${GITEA_RUNNER_NAME:-$(hostname 2>/dev/null || echo act-runner)}" +# Default labels match act_runner register prompts (Docker-based runners). +GITEA_RUNNER_LABELS="${GITEA_RUNNER_LABELS:-}" +ACT_RUNNER_VERSION="${ACT_RUNNER_VERSION:-}" + +for arg in "$@"; do + case "$arg" in + --skip-docker) INSTALL_DOCKER=0 ;; + --no-systemd) INSTALL_SYSTEMD=0 ;; + --skip-apt) SKIP_APT=1 ;; + -h|--help) + sed -n '1,30p' "$0" | tail -n +2 + echo " --skip-docker Skip Docker install (workflows need :host labels or external Docker)" + echo " --no-systemd Do not create/enable act_runner.service" + echo " --skip-apt Skip apt packages and Docker repo setup" + exit 0 + ;; + *) + echo "Unknown option: $arg" >&2 + exit 1 + ;; + esac +done + +if [[ "${EUID:-0}" -ne 0 ]]; then + echo "This script must run as root (e.g. sudo -E $0 ...)" >&2 + exit 1 +fi + +arch_raw="$(uname -m)" +case "$arch_raw" in + x86_64) ACT_ARCH="amd64" ;; + aarch64) ACT_ARCH="arm64" ;; + armv7l) echo "32-bit ARM is not supported by official act_runner Linux builds." >&2; exit 1 ;; + *) echo "Unsupported architecture: $arch_raw" >&2; exit 1 ;; +esac + +if [[ "$SKIP_APT" -eq 0 ]]; then + echo "==> apt: base tools..." + apt-get update + apt-get install -y ca-certificates curl gnupg +fi + +if [[ "$INSTALL_DOCKER" -eq 1 ]]; then + if ! command -v docker &>/dev/null; then + if [[ "$SKIP_APT" -ne 0 ]]; then + echo "Docker is not installed and --skip-apt was set. Install Docker CE first." >&2 + exit 1 + fi + echo "==> Installing Docker Engine (get.docker.com)..." + curl -fsSL https://get.docker.com | sh + else + echo "==> Docker already on PATH, skipping get.docker.com." + fi +fi + +if ! id -u "$ACT_RUNNER_USER" &>/dev/null; then + echo "==> Creating system user $ACT_RUNNER_USER ($ACT_RUNNER_HOME)..." + useradd --system --create-home --home-dir "$ACT_RUNNER_HOME" --shell /bin/bash "$ACT_RUNNER_USER" +else + echo "==> User $ACT_RUNNER_USER already exists." +fi + +if [[ "$INSTALL_DOCKER" -eq 1 ]]; then + usermod -aG docker "$ACT_RUNNER_USER" + systemctl enable --now docker 2>/dev/null || true +fi + +mkdir -p /etc/act_runner +chown root:"$ACT_RUNNER_USER" /etc/act_runner +chmod 750 /etc/act_runner + +if [[ -z "$ACT_RUNNER_VERSION" ]]; then + echo "==> Resolving latest act_runner release from gitea.com API..." + ACT_RUNNER_VERSION="$( + curl -fsS 'https://gitea.com/api/v1/repos/gitea/act_runner/releases/latest' \ + | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\([^"]*\)".*/\1/p' | head -1 + )" + if [[ -z "$ACT_RUNNER_VERSION" ]]; then + echo "Failed to get latest act_runner version. Set ACT_RUNNER_VERSION= manually." >&2 + exit 1 + fi +fi +ACT_VERSION_TAG="v${ACT_VERSION_TAG#v}" +VER_NO_V="${ACT_VERSION_TAG#v}" +DOWNLOAD_URL="https://gitea.com/gitea/act_runner/releases/download/${ACT_VERSION_TAG}/act_runner-${VER_NO_V}-linux-${ACT_ARCH}" + +echo "==> Downloading act_runner ${VER_NO_V} for linux-${ACT_ARCH}..." +tmp="$(mktemp)" +curl -fSL -o "$tmp" "$DOWNLOAD_URL" +install -m 0755 -o root -g root "$tmp" "$ACT_RUNNER_BIN" +rm -f "$tmp" +"$ACT_RUNNER_BIN" --version + +if [[ -f "$ACT_RUNNER_CONFIG" ]]; then + echo "==> $ACT_RUNNER_CONFIG already exists, not overwriting." +else + echo "==> Writing default $ACT_RUNNER_CONFIG ..." + runuser -u "$ACT_RUNNER_USER" -- "$ACT_RUNNER_BIN" generate-config | install -m 0640 -o root -g "$ACT_RUNNER_USER" /dev/stdin "$ACT_RUNNER_CONFIG" +fi + +RUNNER_FILE="${ACT_RUNNER_HOME}/.runner" +if [[ -f "$RUNNER_FILE" ]]; then + echo "==> $RUNNER_FILE already present; skip register. Remove it to re-register." +else + if [[ -n "$GITEA_INSTANCE_URL" && -n "$GITEA_RUNNER_REGISTRATION_TOKEN" ]]; then + echo "==> Registering runner (non-interactive)..." + # Instance URL should be the public Gitea root URL (same as [server] ROOT_URL for most setups). + register_args=(-c "$ACT_RUNNER_CONFIG" register --no-interactive + --instance "$GITEA_INSTANCE_URL" + --token "$GITEA_RUNNER_REGISTRATION_TOKEN" + ) + [[ -n "$GITEA_RUNNER_NAME" ]] && register_args+=(--name "$GITEA_RUNNER_NAME") + if [[ -n "$GITEA_RUNNER_LABELS" ]]; then + register_args+=(--labels "$GITEA_RUNNER_LABELS") + fi + ( + cd "$ACT_RUNNER_HOME" + runuser -u "$ACT_RUNNER_USER" -- env HOME="$ACT_RUNNER_HOME" \ + "$ACT_RUNNER_BIN" "${register_args[@]}" + ) + else + echo "==> No GITEA_INSTANCE_URL + GITEA_RUNNER_REGISTRATION_TOKEN in environment." + echo " To register by hand, run (replace URL and token):" + echo " runuser -u $ACT_RUNNER_USER -- sh -c 'cd $ACT_RUNNER_HOME && HOME=$ACT_RUNNER_HOME $ACT_RUNNER_BIN -c $ACT_RUNNER_CONFIG register --instance https://gitea/ --token TOKEN ...'" + fi +fi + +chown -R "${ACT_RUNNER_USER}:${ACT_RUNNER_USER}" "$ACT_RUNNER_HOME" 2>/dev/null || true + +if [[ ! -f "$RUNNER_FILE" ]]; then + echo "==> Registration did not create $RUNNER_FILE. Start the service after finishing register." +fi + +if [[ "$INSTALL_SYSTEMD" -eq 0 ]]; then + echo "==> Done (--no-systemd). To run: sudo -u $ACT_RUNNER_USER -H sh -c 'cd $ACT_RUNNER_HOME && HOME=$ACT_RUNNER_HOME $ACT_RUNNER_BIN daemon -c $ACT_RUNNER_CONFIG'" + exit 0 +fi + +if [[ "$INSTALL_DOCKER" -eq 1 ]]; then + SD_AFTER="network.target docker.service" + SD_WANTS="Wants=network-online.target" +else + SD_AFTER="network.target" + SD_WANTS="" +fi + +WANTS_BLOCK="" +if [[ -n "${SD_WANTS:-}" ]]; then + WANTS_BLOCK=$'\n'"$SD_WANTS" +fi + +echo "==> Writing /etc/systemd/system/act_runner.service" +cat > /etc/systemd/system/act_runner.service < act_runner status:" + systemctl --no-pager -l status act_runner || true + echo "==> Logs: journalctl -u act_runner -f" +else + echo "==> Service installed but not started (no $RUNNER_FILE). After register: systemctl start act_runner" +fi + +echo "==> Admin UI: \${GITEA_URL}/-/admin/actions/runners"