diff --git a/.env b/.env index 45eb791..ee621ba 100644 --- a/.env +++ b/.env @@ -1,4 +1,5 @@ INSTANCE_URL = https://gitea.digitoolsolutions.synology.me -REGISTRATION_TOKEN = +# REGISTRATION_TOKEN = XlvGTYJfq3FetdGKFIItsDZPJ4BrLRm3iacr8lgv +REGISTRATION_TOKEN = WKo35oM5waFPVyYTwNeiJla3PBpNIB1Dqwq0UpFu # RUNNER_NAME = # RUNNER_LABELS = \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0483914 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +# Dockerfile +FROM ubuntu:24.04 +RUN apt-get update && apt-get install -y \ + openjdk-21-jdk \ + nodejs \ + wget \ + unzip \ + git \ + curl + +# Set environment variables for Android SDK +ENV ANDROID_HOME=/opt/android-sdk +ENV PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH + +# Download and install Android SDK Command-line Tools +RUN mkdir -p $ANDROID_HOME/cmdline-tools/latest \ + && cd $ANDROID_HOME/cmdline-tools/latest \ + && wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O tools.zip \ + && unzip tools.zip \ + && mv cmdline-tools/* . \ + && rm -rf cmdline-tools tools.zip + +# Accept licenses and install required SDK packages +RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses \ + && $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_HOME \ + "platform-tools" "platforms;android-34" "build-tools;34.0.0" + diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..55e66cd --- /dev/null +++ b/Readme.md @@ -0,0 +1,38 @@ +## Generate config file + +`docker run --rm --entrypoint gitea-runner gitea/runner:latest generate-config > config.yaml` + +## config.yaml file + +- On run section: + - Set capacity: int (default: `capacity: 1`) + - Use custom labels: + ``` + lables: + - "android:docker://gitea-runner-android-runner:latest" + ``` + `gitea-runner-android-runner:latest` is custom image + `android` is label use on `workflow`. Example in ci.yaml file: + ``` + runs-on: android + ``` +- On container section: + - Use network (default `network: ""`): + + ``` + network: gitea-actions-network + ``` + + - Mount volume host to job container (default `options: `): + + ``` + options: --volume /d/Workspace/digitoolsolutions/code/gitea-runner/data:/data + ``` + + - Set valid volumes (default `valid_volumes: []`) + + ``` + valid_volumes: + - "/d/Workspace/digitoolsolutions/code/gitea-runner/data" + + ``` diff --git a/config.yaml b/config.yaml index e69de29..59b2b0e 100644 --- a/config.yaml +++ b/config.yaml @@ -0,0 +1,263 @@ +# Example configuration file, it's safe to copy this as the default config file without any modification. + +# You don't have to copy this file to your instance, +# just run `./gitea-runner generate-config > config.yaml` to generate a config file. + +# Logging for the runner process itself (messages printed to stderr). +# This does not control how workflow step output is streamed to the Gitea UI; +# tune that with runner.log_report_* below. +log: + # logrus severity: trace, debug, info, warn, error, fatal, panic. + # trace and debug turn on caller/file:line in log lines. Default if omitted: info. + level: info + +runner: + # Where to store the registration result. + file: .runner + # Execute how many tasks concurrently at the same time. + # With `container.network` empty, each concurrent docker job takes a subnet from the + # daemon's address pool, so a high capacity can exhaust it. See `default-address-pools` + # in the docker daemon config. + capacity: 2 + # Extra environment variables to run jobs. + envs: + A_TEST_ENV_NAME_1: a_test_env_value_1 + A_TEST_ENV_NAME_2: a_test_env_value_2 + # Extra environment variables to run jobs from a file. + # It will be ignored if it's empty or the file doesn't exist. + env_file: .env + # The timeout for a job to be finished. + # Please note that the Gitea instance also has a timeout (3h by default) for the job. + # So the job could be stopped by the Gitea instance if its timeout is shorter than this. + timeout: 3h + # The timeout for the runner to wait for running jobs to finish when shutting down. + # Any running jobs that haven't finished after this timeout will be cancelled. + shutdown_timeout: 0s + # Whether skip verifying the TLS certificate of the Gitea instance. + insecure: false + # The timeout for fetching the job from the Gitea instance. + fetch_timeout: 5s + # The interval for fetching the job from the Gitea instance. + fetch_interval: 2s + # The maximum interval for fetching the job from the Gitea instance. + # The runner uses exponential backoff when idle, increasing the interval up to this maximum. + # Set to 0 or same as fetch_interval to disable backoff. + fetch_interval_max: 5s + # While idle, remove stale bind-workdir task directories and orphaned host-mode + # scratch directories (left behind when a host cleanup delete stalls) older than + # this duration. Setting either workdir_cleanup_age or idle_cleanup_interval to 0 + # (or any non-positive value) disables stale-directory cleanup entirely, along with + # the docker network cleanup below. + workdir_cleanup_age: 24h + # Cadence for the idle cleanup pass. Besides the directories above, on runners that use + # docker it removes the per-job networks of jobs this runner did not live to tear down, + # which would otherwise hold a subnet of the daemon address pool until the host is rebuilt. + idle_cleanup_interval: 10m + # The base interval for periodic log flush to the Gitea instance. + # Logs may be sent earlier if the buffer reaches log_report_batch_size + # or if log_report_max_latency expires after the first buffered row. + log_report_interval: 5s + # The maximum time a log row can wait before being sent. + # This ensures even a single log line appears on the frontend within this duration. + # Must be less than log_report_interval to have any effect. + log_report_max_latency: 3s + # Flush logs immediately when the buffer reaches this many rows. + # This ensures bursty output (e.g., npm install) is delivered promptly. + log_report_batch_size: 100 + # The interval for reporting task state (step status, timing) to the Gitea instance. + # State is also reported immediately on step transitions (start/stop). + state_report_interval: 5s + # Per-attempt deadline for flushing the final logs and task state when a job + # finishes, on a detached context so a server cancel can't block the acknowledgement. + report_close_timeout: 10s + # The github_mirror of a runner is used to specify the mirror address of the github that pulls the action repository. + # It works when something like `uses: actions/checkout@v4` is used and DEFAULT_ACTIONS_URL is set to github, + # and github_mirror is not empty. In this case, + # it replaces https://github.com with the value here, which is useful for some special network environments. + github_mirror: "" + # When true (the default), fetch only the requested ref of an action repository (e.g. actions/checkout@v4) at depth 1 instead of cloning every branch's full history. + # Set to false to clone the full history. + action_shallow_clone: true + # When true (the default), inject the ACT=true environment variable into jobs. + # Set to false so workflows gated on `if: ${{ !env.ACT }}` behave like they do on GitHub. + set_act_env: true + # The labels of a runner are used to determine which jobs the runner can run, and how to run them. + # Like: "macos-arm64:host" or "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest" + # Find more images provided by Gitea at https://gitea.com/gitea/runner-images . + # If it's empty when registering, it will ask for inputting labels. + # If it's empty when execute `daemon`, will use labels in `.runner` file. + labels: + - "android:docker://gitea-runner-android-runner:latest" #### Use the runner's own image for Android jobs, which has the Android SDK preinstalled. + - "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest" + - "ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04" + - "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04" + # Allocate a pseudo-TTY for each step's process. Applies to both host and docker backends. + # Default false matches GitHub actions/runner. Enable only for jobs that need an interactive + # terminal; tools like `docker build` emit redrawing progress frames into the captured log + # when a TTY is present. + allocate_pty: false + # Optional executable on the host, run once after each task's built-in cleanup + # (post-steps, container teardown, bind-workdir removal). Additive only. + # + # IMPORTANT: While this script runs the runner stops task heartbeats and stays + # offline from Gitea's perspective until the script exits. A script that never + # returns blocks new work until post_task_script_timeout kills it (default 5m). + # Keep scripts short; set post_task_script_timeout to a safe upper bound. + # + # Output -> runner process log (not the job log). Non-zero exit -> warning only. + # Windows: use .exe, .bat, or .cmd. PowerShell (.ps1) is not supported yet as + # the configured path; wrap PowerShell commands in a .cmd file instead. + # Full guide: docs/post-task-script.md + post_task_script: "" + # Hard limit on post_task_script runtime. Default if omitted: 5m. + post_task_script_timeout: 5m + # Scripts run inside the job environment before the job's first step and after its last + # one, the equivalent of GitHub's ACTIONS_RUNNER_HOOK_JOB_STARTED and + # ACTIONS_RUNNER_HOOK_JOB_COMPLETED, which are read when these are unset. The paths are + # resolved inside the job environment. Either one failing fails the job. + # Full guide: docs/job-hooks.md + hooks: + job_started: "" + job_completed: "" + +cache: + # Enable the built-in cache server (used by actions/cache and similar actions). + enabled: true + # Directory where cache blobs are stored on disk. Default: $HOME/.cache/actcache + # Ignored when external_server is set. + dir: "" + # Outbound IP or hostname that job containers use to reach this runner's cache server. + # Leave empty to detect automatically. 0.0.0.0 is not valid here. + # If the runner itself runs in Docker, automatic detection can choose an + # address on the runner container's network that job containers cannot reach + # when the runner creates a separate per-job network. In that case, set this + # to a hostname/IP reachable from job containers, and set port to a fixed + # published port or put the job containers on a shared Docker network. + # Ignored when external_server is set. + host: "" + # Port for the built-in cache server. 0 picks a random free port. + # Ignored when external_server is set. + port: 0 + # URL of a shared `gitea-runner cache-server` to use instead of starting a local one. + # Set on every runner that should share a cache pool. A trailing slash is optional. + # Example: "http://cache-host:8088/" + # Requires external_secret (below) to match the value on the cache-server. + external_server: "" + # Shared secret between this runner and the external cache-server. + # Required when external_server is set. Must be identical on every runner and the cache-server. + # Generate with: openssl rand -hex 32 + external_secret: "" + # Path to a file containing the shared secret, as an alternative to external_secret. + # Use this to keep the secret out of this file. + # Surrounding whitespace is trimmed, so a trailing newline in the file is fine. + # Setting both external_secret and external_secret_file is an error. + external_secret_file: "" + # When true, reuse a cached action instead of fetching from the remote on every job. + # A moved tag (e.g. a re-tagged "v6") or an updated branch stays at the cached commit + # until its cache entry expires or is manually removed. + offline_mode: false + # Serve the actions cache service v2 API, used by actions/cache@v4.2 and later. Those actions + # refuse any host they do not take for GitHub, so reaching it means editing that check out of + # the action's own bundle, keeping the untouched copy beside it. The same edit lets the stock + # upload-artifact and download-artifact work here. A bundle that does not match is left alone. + v2: true + +container: + # Specifies the network to which the container will connect. + # Could be host, bridge or the name of a custom network. + # If it's empty, runner will create a network automatically. + # For dockerized runners using the built-in cache server, a custom shared + # network can be required so job containers can reach cache.host/cache.port. + # Deprecated: `network_mode` is still accepted for old configs; use `network` instead. + network: gitea-actions-network + # network_create_options only apply when `network` is left empty and the runner + # auto-creates a per-job network that does not already exist. They have no effect + # when a custom `network` name is set, because that network is used as-is and never + # created by the runner. Omit the entire block to use Docker's defaults. An auto-created + # network is labelled com.gitea.runner.uuid=, which is how the idle + # cleanup tells its own leftovers apart from those of other runners on the same daemon. + network_create_options: + enable_ipv4: true # Omit to use Docker's default (IPv4 enabled). Set false to disable IPv4. + enable_ipv6: false # Omit to use Docker's default (IPv6 disabled). Enabling it requires dockerd started with --ipv6. + # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). + privileged: false + # Any other options to be used when the container is started, for example: + # options: --add-host=my.gitea.url:host-gateway + # A volume declared here replaces the one the runner mounts on the same container path, so the + # tool cache can be kept on the host. Its source must also be allowed by valid_volumes below: + # options: --volume /host/toolcache:/opt/hostedtoolcache + options: --volume /d/Workspace/digitoolsolutions/code/gitea-runner/data:/data + # The parent directory of a job's working directory. + # NOTE: There is no need to add the first '/' of the path as runner will add it automatically. + # If the path starts with '/', the '/' will be trimmed. + # For example, if the parent directory is /path/to/my/dir, workdir_parent should be path/to/my/dir + # If it's empty, /workspace will be used. + # Purely numeric subdirectories under this path are reserved for task workspaces and may be removed by idle cleanup. + workdir_parent: + # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob + # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted. + # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to: + # valid_volumes: + # - data + # - /src/*.json + # If you want to allow any volume, please use the following configuration: + # valid_volumes: + # - '**' + + valid_volumes: + - "/d/Workspace/digitoolsolutions/code/gitea-runner/data" + # Overrides the docker client host with the specified one. + # If it's empty, runner will find an available docker host automatically. + # If it's "-", runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers. + # If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work. + docker_host: "" + # Pull docker image(s) even if already present. + # Defaults to false when the key is omitted. + # Two exceptions: an image pinned by digest (image@sha256:...) cannot change, so it is never + # re-pulled, and a pull that fails while a copy is already on the host does not fail the job, + # which runs on that copy with a warning in its log. + force_pull: false + # Rebuild docker image(s) even if already present + force_rebuild: false + # Always require a reachable docker daemon, even if not required by runner + require_docker: false + # Timeout to wait for the docker daemon to be reachable, if docker is required by require_docker or runner + docker_timeout: 0s + # Bind the workspace to the host filesystem instead of using Docker volumes. + # This is required for Docker-in-Docker (DinD) setups when jobs use docker compose + # with bind mounts (e.g., ".:/app"), as volume-based workspaces are not accessible + # from the DinD daemon's filesystem. When enabled, ensure the workspace parent + # directory is also mounted into the runner container and listed in valid_volumes. + bind_workdir: false + +host: + # The parent directory of a job's working directory. + # If it's empty, $HOME/.cache/act/ will be used. + workdir_parent: + +# Optional local task-admission checks. Disabled by default. When enabled, low +# disk space or a failing script pauses new task fetching; existing jobs continue. +# No health checks run while any job is active; the last result is reused until idle. +health_check: + enabled: false + # Minimum free space required on the filesystem holding runner workspaces. + # Defaults to 1024 MiB when omitted or set to zero. + min_free_disk_space_mb: 1024 + # Optional additional executable. A non-zero exit, timeout, or startup failure + # marks the runner unavailable. + script: "" + # How long a script result is cached and its maximum execution time. + interval: 30s + timeout: 10s + +metrics: + # Enable the Prometheus metrics endpoint. + # When enabled, metrics are served at /metrics, liveness at /healthz, and + # task-admission readiness at /readyz. + enabled: false + # The address for the metrics HTTP server to listen on. + # Defaults to localhost only. Set to ":9101" to allow external access, + # but ensure the port is firewall-protected as there is no authentication. + addr: "127.0.0.1:9101" + # Consecutive polling failures may last this long before /readyz returns 503. + readiness_grace: 30s diff --git a/docker-compose.yaml b/docker-compose.yaml index 24710df..638085b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,15 +1,38 @@ services: runner: - image: docker.io/gitea/runner:latest - container_name: gitea-runner + image: docker.io/gitea/runner:3.1.0 + container_name: runner restart: unless-stopped + environment: CONFIG_FILE: /config.yaml GITEA_INSTANCE_URL: "${INSTANCE_URL}" GITEA_RUNNER_REGISTRATION_TOKEN: "${REGISTRATION_TOKEN}" - GITEA_RUNNER_NAME: "${RUNNER_NAME}" - GITEA_RUNNER_LABELS: "${RUNNER_LABELS}" + # GITEA_RUNNER_NAME: "${RUNNER_NAME}" + # GITEA_RUNNER_LABELS: "${RUNNER_LABELS}" + + networks: + - gitea-actions-network volumes: - ./config.yaml:/config.yaml - - ./data:/data - - /var/run/docker.sock:/var/run/docker.sock \ No newline at end of file + - /var/run/docker.sock:/var/run/docker.sock + + android-runner: + build: + context: . + dockerfile: Dockerfile + container_name: android-runner + restart: unless-stopped + command: > + bash -c " + echo '=== Android Runner Ready ==='; + java -version; + echo ANDROID_HOME=$ANDROID_HOME; + sdkmanager --version; + tail -f /dev/null + " + +networks: + gitea-actions-network: + name: gitea-actions-network + external: true \ No newline at end of file