From deefb19f21f544504d4b4af9d22165c80d81ec74 Mon Sep 17 00:00:00 2001
From: Earl Warren <contact@earl-warren.org>
Date: Thu, 24 Aug 2023 12:28:17 +0200
Subject: [PATCH] example docker compose file and test

---
 .forgejo/workflows/example-docker-compose.yml | 52 +++++++++++
 examples/docker-compose/README.md             | 87 +++++++++++++++----
 .../docker-compose/compose-demo-workflow.yml  | 38 ++++++++
 .../compose-forgejo-and-runner.yml            | 68 +++++++++++++++
 4 files changed, 228 insertions(+), 17 deletions(-)
 create mode 100644 .forgejo/workflows/example-docker-compose.yml
 create mode 100644 examples/docker-compose/compose-demo-workflow.yml
 create mode 100644 examples/docker-compose/compose-forgejo-and-runner.yml

diff --git a/.forgejo/workflows/example-docker-compose.yml b/.forgejo/workflows/example-docker-compose.yml
new file mode 100644
index 0000000..465e80b
--- /dev/null
+++ b/.forgejo/workflows/example-docker-compose.yml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: MIT
+on: [push]
+
+jobs:
+  example-docker-compose:
+    runs-on: self-hosted
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Install docker
+        run: |
+          apt-get update -qq
+          export DEBIAN_FRONTEND=noninteractive
+          apt-get install -qq -y ca-certificates curl gnupg
+          install -m 0755 -d /etc/apt/keyrings
+          curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
+          echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+          apt-get update -qq
+          apt-get install -qq -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin=2.20.2-1~debian.11~bullseye
+          docker version
+          #
+          # docker compose is prone to non backward compatible changes, pin it
+          #
+          apt-get install -qq -y docker-compose-plugin=2.20.2-1~debian.11~bullseye
+          docker compose version
+
+      - name: run the example
+        run: |
+          set -x
+          cd examples/docker-compose
+          cli="docker compose -f compose-forgejo-and-runner.yml -f compose-demo-workflow.yml"
+          #
+          # Launch
+          #
+          $cli up -d
+          #
+          # Wait for the demo workflow to complete
+          #
+          $cli ps --help
+          success='DEMO WORKFLOW SUCCESS'
+          for delay in $(seq 60) ; do
+            $cli logs -n 10 demo-workflow > /tmp/out
+            grep --quiet "$success" /tmp/out && break
+            $cli ps --all
+            cat /tmp/out
+            sleep 10
+          done
+          if ! grep --quiet "$success" /tmp/out ; then
+            echo ==========================================
+            $cli logs
+            exit 1
+          fi
diff --git a/examples/docker-compose/README.md b/examples/docker-compose/README.md
index c3b714c..166fc41 100644
--- a/examples/docker-compose/README.md
+++ b/examples/docker-compose/README.md
@@ -1,20 +1,73 @@
-### Running `act_runner` using `docker-compose`
+## Docker compose with docker-in-docker
 
-```yml
+The `compose-forgejo-and-runner.yml` compose file runs a Forgejo
+instance and registers a `Forgejo runner`. A docker server is also
+launched within a container (using
+[dind](https://hub.docker.com/_/docker/tags?name=dind)) and will be
+used by the `Forgejo runner` to execute the workflows.
+
+### Running
+
+```sh
+docker-compose -f compose-forgejo-and-runner.yml up
+Creating docker-compose_docker-in-docker_1 ... done
+Creating docker-compose_forgejo_1          ... done
+Creating docker-compose_runner-register_1  ... done
+...
+docker-in-docker_1  | time="2023-08-24T10:22:15.023338461Z" level=warning msg="WARNING: API is accessible on http://0.0.0.0:2375
+...
+forgejo_1           | 2023/08/24 10:22:14 ...s/graceful/server.go:75:func1() [D] Starting server on tcp:0.0.0.0:3000 (PID: 19)
+...
+runner-daemon_1     | time="2023-08-24T10:22:16Z" level=info msg="Starting runner daemon"
+```
+
+### Manual testing
+
+To login the Forgejo instance:
+
+* URL: http://0.0.0.0:8080
+* user: root
+* password: admin1234
+
+`Forgejo Actions` is enabled by default when creating a repository.
+
+### Security
+
+This is a demo and **must not be used in production** because:
+
+* the runner secret is hardcoded
+* the admin password is hardcoded to admin1234
+
+## Tests workflow
+
+The `compose-demo-workflow.yml` compose file runs a demo workflow to
+verify the `Forgejo runner` can pick up a task from the Forgejo instance
+and run it to completion.
+
+A new repository is created in root/test with the following workflow
+in `.forgejo/workflows/demo.yml`:
+
+```yaml
+on: [push]
+jobs:
+  test:
+    runs-on: docker
+    steps:
+      - run: echo All Good
+```
+
+A wait loop expects the status of the check associated with the
+commit in Forgejo to show "success" to assert the workflow was run.
+
+### Running
+
+```sh
+$ docker-compose -f compose-forgejo-and-runner.yml -f compose-demo-workflow.yml up demo-workflow
+...
+demo-workflow_1     | To http://forgejo:3000/root/test
+demo-workflow_1     |  + 5ce134e...261cc79 main -> main (forced update)
+demo-workflow_1     | branch 'main' set up to track 'http://root:admin1234@forgejo:3000/root/test/main'.
+...
+demo-workflow_1     | running
 ...
-  gitea:
-    image: gitea/gitea
-    ...
-
-  runner:
-    image: gitea/act_runner
-    restart: always
-    depends_on:
-      - gitea
-    volumes:
-      - ./data/act_runner:/data
-      - /var/run/docker.sock:/var/run/docker.sock
-    environment:
-      - GITEA_INSTANCE_URL=<instance url>
-      - GITEA_RUNNER_REGISTRATION_TOKEN=<registration token>
 ```
diff --git a/examples/docker-compose/compose-demo-workflow.yml b/examples/docker-compose/compose-demo-workflow.yml
new file mode 100644
index 0000000..2f61d4a
--- /dev/null
+++ b/examples/docker-compose/compose-demo-workflow.yml
@@ -0,0 +1,38 @@
+# Copyright 2023 The Forgejo Authors.
+# SPDX-License-Identifier: MIT
+
+version: "3"
+
+services:
+
+  demo-workflow:
+    image: alpine:3.18
+    links:
+      - forgejo
+    depends_on:
+      runner-register:
+        condition: service_completed_successfully
+    command: >-
+      sh -xc '
+      apk add --quiet git curl jq ;
+      mkdir -p /srv/demo ;
+      cd /srv/demo ;
+      git init --initial-branch=main ;
+      mkdir -p .forgejo/workflows ;
+      echo "{ on: [push], jobs: { test: { runs-on: docker, steps: [ { run: echo All Good } ] } } }" > .forgejo/workflows/demo.yml ;
+      git add . ;
+      git config user.email root@example.com ;
+      git config user.name username ;
+      git commit -m 'demo' ;
+      while : ; do
+        git push --set-upstream --force http://root:admin1234@forgejo:3000/root/test main && break ;
+        sleep 5 ;
+      done ;
+      sha=`git rev-parse HEAD` ;
+      while : ; do
+        curl -sS -f http://forgejo:3000/api/v1/repos/root/test/commits/$$sha/status | jq --raw-output .state | tee status ;
+        grep success status && break ;
+        sleep 5 ;
+      done ;
+      echo DEMO WORKFLOW SUCCESS
+      '
diff --git a/examples/docker-compose/compose-forgejo-and-runner.yml b/examples/docker-compose/compose-forgejo-and-runner.yml
new file mode 100644
index 0000000..75ca5c1
--- /dev/null
+++ b/examples/docker-compose/compose-forgejo-and-runner.yml
@@ -0,0 +1,68 @@
+# Copyright 2023 The Forgejo Authors.
+# SPDX-License-Identifier: MIT
+
+version: "3"
+
+services:
+
+  docker-in-docker:
+    image: docker:dind
+    privileged: true
+    command: [ "dockerd", "-H", "tcp://0.0.0.0:2375", "--tls=false" ]
+
+  forgejo:
+    image: codeberg.org/forgejo/forgejo:1.20.3-0
+    command: >-
+      bash -c '
+      /bin/s6-svscan /etc/s6 &
+      sleep 10 ;
+      su -c "forgejo forgejo-cli actions register --secret e3359786173a7aeb3818c19637479c5dbd7c5abb --labels docker --version 3.0.0" git ;
+      su -c "forgejo admin user create --admin --username root --password admin1234 --email root@example.com" git ;
+      sleep infinity
+      '
+    environment:
+      FORGEJO__security__INSTALL_LOCK: "true"
+      FORGEJO__log__LEVEL: "debug"
+      FORGEJO__actions__ENABLED: "true"
+      FORGEJO__repository__ENABLE_PUSH_CREATE_USER: "true"
+      FORGEJO__repository__DEFAULT_PUSH_CREATE_PRIVATE: "false"
+      FORGEJO__repository__DEFAULT_REPO_UNITS: "repo.code,repo.actions"
+    volumes:
+      - /srv/forgejo-data:/data
+    ports:
+      - 8080:3000
+
+  runner-register:
+    image: code.forgejo.org/forgejo/runner:3.0.0
+    links:
+      - docker-in-docker
+      - forgejo
+    environment:
+      DOCKER_HOST: tcp://docker-in-docker:2375
+    volumes:
+      - /srv/runner-data:/data
+    user: 0:0
+    command: >-
+      bash -c '
+      while : ; do
+        forgejo-runner create-runner-file --instance http://forgejo:3000 --name runner --secret e3359786173a7aeb3818c19637479c5dbd7c5abb && break ;
+        sleep 1 ;
+      done ;
+      forgejo-runner generate-config > config.yml ;
+      sed -i -e "s|labels: \[\]|labels: \[\"docker:docker://alpine:3.18\"\]|" config.yml ;
+      chown -R 1000:1000 /data
+      '
+
+  runner-daemon:
+    image: code.forgejo.org/forgejo/runner:3.0.0
+    links:
+      - docker-in-docker
+      - forgejo
+    environment:
+      DOCKER_HOST: tcp://docker-in-docker:2375
+    depends_on:
+      runner-register:
+        condition: service_completed_successfully
+    volumes:
+      - /srv/runner-data:/data
+    command: "forgejo-runner --config config.yml daemon"