diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml
new file mode 100644
index 0000000..d4e678c
--- /dev/null
+++ b/.gitea/workflows/ci.yaml
@@ -0,0 +1,62 @@
+name: sampleapp-cicd
+
+on:
+ push:
+ branches: ["**"]
+ pull_request:
+
+jobs:
+ ci:
+ runs-on: ubuntu-latest
+ env:
+ REGISTRY: gitea.tests01.helity.org
+ IMAGE: gitea.tests01.helity.org/lab/sampleapp
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Lint / validate content
+ run: |
+ set -e
+ test -f index.html
+ test -f Dockerfile
+ grep -q "
" index.html
+ grep -q "FROM nginx" Dockerfile
+ echo "lint OK"
+
+ - name: Inject commit SHA into page
+ run: |
+ set -e
+ sed -i "s/__GIT_SHA__/${GITHUB_SHA}/g" index.html
+ grep -q "${GITHUB_SHA}" index.html && echo "sha injected: ${GITHUB_SHA}"
+
+ - name: Build image
+ run: |
+ set -e
+ docker build -t "${IMAGE}:${GITHUB_SHA}" -t "${IMAGE}:latest" .
+
+ - name: Push image (main only)
+ if: github.ref == 'refs/heads/main'
+ run: |
+ set -e
+ echo "${{ secrets.REGISTRY_TOKEN }}" | docker login "${REGISTRY}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin
+ docker push "${IMAGE}:${GITHUB_SHA}"
+ docker push "${IMAGE}:latest"
+ docker logout "${REGISTRY}"
+
+ deploy:
+ runs-on: ubuntu-latest
+ needs: ci
+ if: github.ref == 'refs/heads/main'
+ steps:
+ - name: Trigger Rundeck deploy job
+ run: |
+ set -e
+ code=$(curl -fsS -o /tmp/rd.json -w '%{http_code}' -X POST \
+ -H "X-Rundeck-Auth-Token: ${{ secrets.RUNDECK_TOKEN }}" \
+ -H "Content-Type: application/json" \
+ -H "Accept: application/json" \
+ "${{ secrets.RUNDECK_URL }}/api/40/job/${{ secrets.DEPLOY_JOB_UUID }}/run" \
+ --data "{\"options\":{\"image_tag\":\"${GITHUB_SHA}\"}}")
+ echo "Rundeck run HTTP ${code}"
+ python3 -c "import json;d=json.load(open('/tmp/rd.json'));print('execution id:',d.get('id'),'status:',d.get('status'),'permalink:',d.get('permalink'))"
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5ebe438
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,3 @@
+FROM nginx:alpine
+COPY index.html /usr/share/nginx/html/index.html
+EXPOSE 80
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..9dfbf90
--- /dev/null
+++ b/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+ sampleapp — CI/CD deployed
+
+
+
+
+ sampleapp · live
+ Deployed via the GitOps pipeline
+
+ This page is served by the container image built and pushed by
+ Gitea Actions , then deployed to rocky10 by a
+ Rundeck job that the CI workflow triggered over the Rundeck API.
+
+ commit __GIT_SHA__
+ The pipeline that produced this page:
+
+ push to lab/sampleapp on the lab Gitea
+ Gitea Actions runner: lint → docker build → push image to the Gitea registry
+ on main: workflow calls the Rundeck API
+ Rundeck deploys this image on rocky10 and writes an audited marker on debian13b via Teleport
+
+ Elyrix lab · Gitea Actions → Rundeck CI/CD demo
+
+
+