diff --git a/.gitea/scripts/deploy-and-restart-service.sh b/.gitea/scripts/deploy-and-restart-service.sh new file mode 100755 index 0000000..4bc01d5 --- /dev/null +++ b/.gitea/scripts/deploy-and-restart-service.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +SERVICE_NAME=$1 +AGEBD_ENV=$2 + +echo "==========================================" +echo "Deploying service: $SERVICE_NAME (${AGEBD_ENV})" +echo "==========================================" + +SERVICE_NAME_LOWER=$(echo "$SERVICE_NAME" | tr '[:upper:]' '[:lower:]') +SERVICE_NAME_UPPER=$(echo "$SERVICE_NAME" | tr '[:lower:]' '[:upper:]') +SERVICE_DIR=/sls/bd/hla/${AGEBD_ENV}/services/${SERVICE_NAME_LOWER}/current +SYSTEMD_UNIT_NAME=AGEBD-SERVICE-${SERVICE_NAME_UPPER}.service +SYSTEMD_UNIT_FILE_PATH=${SERVICE_DIR}/systemd/${SYSTEMD_UNIT_NAME} + +mkdir -p ${SERVICE_DIR} + +rsync -avz --delete --exclude='.venv' \ + ./services/${SERVICE_NAME_LOWER}/current/ \ + ${SERVICE_DIR}/ + + +if [ -f "${SYSTEMD_UNIT_FILE_PATH}" ]; then + sed -i "s/{{ *agebd_env* }}/${AGEBD_ENV}/g" "${SYSTEMD_UNIT_FILE_PATH}" +fi + +mkdir -p ${HOME}/.config/systemd/user +ln -sf "${SYSTEMD_UNIT_FILE_PATH}" "${HOME}/.config/systemd/user/${SYSTEMD_UNIT_NAME}" + +export XDG_RUNTIME_DIR="/run/user/$(id -u)" +systemctl --user daemon-reload +systemctl --user enable "${SYSTEMD_UNIT_NAME}" +systemctl --user restart "${SYSTEMD_UNIT_NAME}" diff --git a/.gitea/workflows/add-new-service.yml b/.gitea/workflows/add-new-service.yml index 1471f16..dc6ae77 100644 --- a/.gitea/workflows/add-new-service.yml +++ b/.gitea/workflows/add-new-service.yml @@ -10,9 +10,6 @@ jobs: deploy: runs-on: hla-dev - env: - ANSIBLE_CONFIG: "${{ github.workspace }}/ansible/ansible.cfg" - steps: - name: Checkout repository uses: actions/checkout@v4 @@ -38,36 +35,19 @@ jobs: SERVICE_NAME="${BRANCH#feature/add-service-}" echo "service_name_lower=$SERVICE_NAME" >> $GITHUB_OUTPUT - # TODO: look into venv caching (will do later in case we move from uv to pixi) - # - name: Cache Python Virtual Environment - # uses: actions/cache@v4 - # with: - # path: .venv - # # Changes uv.lock will automatically invalidate the cache and rebuild - # key: ${{ runner.os }}-uv-cli-venv-${{ hashFiles('cli/uv.lock') }} - # restore-keys: | - # ${{ runner.os }}-uv-cli-venv- + # - name: Install Master IOC - # # Only create the venv if the cache didn't restore an existing one - # if [ ! -d ".venv" ]; then - # echo "Building new .venv" - # uv venv .venv - # fi - - name: Initialize Virtual Environment from cli/uv.lock - run: | - uv venv .venv - uv sync --directory cli + # - name: Restart Master IOC - - name: Install Ansible Galaxy Collections + - name: Deploy and Restart Master Service run: | - uv run ansible-galaxy collection install -r ansible/collections/requirements.yml -p ./ansible/installed-collections + ./.gitea/scripts/deploy-and-restart-service.sh "master" "dev" - # TODO: dev/prod - - name: Run New Service Playbook - working-directory: ansible + # - name: Install New IOC + + # - name: Start New IOC + + - name: Deploy and Restart New Service run: | - uv run ansible-playbook playbooks/add-new-service.yml \ - -i "inventories/dev/hosts.yml" \ - --extra-vars="repo_root=${{ github.workspace }}" \ - --extra-vars="service_name_lower=${{ steps.parse_branch.outputs.service_name_lower }}" \ - -v + SERVICE_NAME=${{ steps.parse_branch.outputs.service_name_lower }} + ./.gitea/scripts/deploy-and-restart-service.sh "${SERVICE_NAME}" "dev" diff --git a/.gitea/workflows/deploy-py-agebd-pypi.yml b/.gitea/workflows/deploy-py-agebd-pypi.yml deleted file mode 100644 index 87b5b24..0000000 --- a/.gitea/workflows/deploy-py-agebd-pypi.yml +++ /dev/null @@ -1,13 +0,0 @@ -# name: Deploy agebd python package to gitea/pypi -# -# # TODO: services depend on this workflow -# on: -# push: -# branches: -# - main -# paths: -# - 'packages/agebd/**' -# -# jobs: -# deploy: -# runs-on: hla-dev diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 09353e2..dae043b 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -13,23 +13,27 @@ on: - 'qt/**' - 'services/**' +# Cancel previous runs if a new commit is pushed to the same branch +concurrency: + group: deploy-${{ github.ref }} + cancel-in-progress: true + +env: + # commit tagged ? yes->prod : no->dev + AGEBD_ENV: ${{ github.ref_type == 'tag' && 'prod' || 'dev' }} jobs: deploy: runs-on: hla-dev - env: - # commit tagged ? yes->prod : no->dev - AGEBD_ENV: ${{ github.ref_type == 'tag' && 'prod' || 'dev' }} - steps: - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 2 # needed for git diff tracking + fetch-depth: 0 # Needed for git diff in service detection - - name: Defined filter paths - uses: actions/paths-filter@v3 # see: https://gitea.psi.ch/actions/paths-filter + - name: Define filter paths + uses: actions/paths-filter@v3 id: filter with: filters: | @@ -43,7 +47,7 @@ jobs: - 'services/**' - name: Install uv - uses: actions/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: actions/setup-uv@v5 - name: Install Python 3.10 run: uv python install 3.10 @@ -52,76 +56,54 @@ jobs: run: | cd scripts && uv run pytest - # TODO: maybe this is better: `rsync -av --delete ./ "${DEST_DIR}/"` # Sync everything perfectly, including hidden files, and delete old stale files + # ----------------------------------------------------------------- + # Directory Deployments + # ----------------------------------------------------------------- - name: Bin - deploy if: steps.filter.outputs.bin == 'true' env: - # commit tagged ? yes->prod : no->dev - DEST_DIR: /sls/bd/hla/${{ github.ref_type == 'tag' && 'prod' || 'dev' }}/bin - working-directory: bin + DEST_DIR: /sls/bd/hla/${{ env.AGEBD_ENV }}/bin run: | - mkdir -p ${DEST_DIR} - cp -r ./* ${DEST_DIR} + mkdir -p "${DEST_DIR}" + rsync -av --delete --exclude='.nfs*' ./bin/ "${DEST_DIR}/" - # TODO: maybe this is better: `rsync -av --delete ./ "${DEST_DIR}/"` # Sync everything perfectly, including hidden files, and delete old stale files - name: Agebd - deploy if: steps.filter.outputs.agebd == 'true' env: - # commit tagged ? yes->prod : no->dev - DEST_DIR: /sls/bd/hla/${{ github.ref_type == 'tag' && 'prod' || 'dev' }}/packages/agebd - working-directory: packages/agebd + DEST_DIR: /sls/bd/hla/${{ env.AGEBD_ENV }}/packages/agebd run: | - mkdir -p ${DEST_DIR} - cp -r ./* ${DEST_DIR} + mkdir -p "${DEST_DIR}" + rsync -av --delete --exclude='.nfs*' ./packages/agebd/ "${DEST_DIR}/" - # TODO: maybe this is better: `rsync -av --delete ./ "${DEST_DIR}/"` # Sync everything perfectly, including hidden files, and delete old stale files - name: Qt - deploy if: steps.filter.outputs.qt == 'true' env: - # commit tagged ? yes->prod : no->dev - DEST_DIR: /sls/bd/hla/${{ github.ref_type == 'tag' && 'prod' || 'dev' }}/qt - working-directory: qt + DEST_DIR: /sls/bd/hla/${{ env.AGEBD_ENV }}/qt run: | - mkdir -p ${DEST_DIR} - cp -r ./* ${DEST_DIR} + mkdir -p "${DEST_DIR}" + rsync -av --delete --exclude='.nfs*' ./qt/ "${DEST_DIR}/" - # TODO: (when) do we need to restart the master service or reinstall/restart the master ioc? - - - name: Services - Initialize Virtual Environment from cli/uv.lock + # ----------------------------------------------------------------- + # Services Deployment + # ----------------------------------------------------------------- + - name: Deploy Changed Services if: steps.filter.outputs.services == 'true' run: | - uv venv .venv - uv sync --directory cli + # 1. Determine git comparison point + BEFORE="${{ github.event.before }}" + if [ -z "$BEFORE" ] || [ "$BEFORE" = "0000000000000000000000000000000000000000" ]; then + BEFORE="HEAD~1" + fi - - name: Services - Install Ansible Galaxy Collections - if: steps.filter.outputs.services == 'true' - run: | - uv run ansible-galaxy collection install -r ansible/collections/requirements.yml -p ./ansible/installed-collections + # 2. Extract list of modified service folder names + CHANGED_SERVICES=$(git diff --name-only "$BEFORE" "${{ github.sha }}" | awk -F/ '$1=="services" && $2!="" {print $2}' | sort -u) - - name: Services - Run Ansible Orchestrator - if: steps.filter.outputs.services == 'true' - working-directory: ansible - run: | - set -x - - # Disable pipefail temporarily or add an '|| true' fallback so grep doesn't kill the script - set +e - CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }}) - set -e - - # 1. Parse changed directory names into space-separated string (e.g. "master other-service") - CHANGED_SVC=$(echo "$CHANGED_FILES" | awk -F/ '$1=="services" {print $2}' | sort -u | xargs) - - echo "Detected changed services: '$CHANGED_SVC'" - - # Safely halt the execution if there is nothing to pass to Ansible - if [ -z "$CHANGED_SVC" ]; then - echo "No services changed in this commit range. Skipping deployment smoothly." + if [ -z "$CHANGED_SERVICES" ]; then + echo "No service directory changes detected in diff." exit 0 fi - # 3. Fire the playbook passing variables down - ansible-playbook playbooks/deploy-and-restart-modified-services.yml \ - -i "inventories/$AGEBD_ENV/hosts.yml" \ - --extra-vars="changed_services_raw='$CHANGED_SVC'" \ - -v + # 3. Loop through changed services and invoke deployment script + echo "$CHANGED_SERVICES" | while read -r SERVICE; do + ./.gitea/scripts/deploy-and-restart-service.sh "${SERVICE}" "${AGEBD_ENV}" + done diff --git a/bin/start_service.sh b/bin/start_service.sh index 24dda0c..ce12f1a 100755 --- a/bin/start_service.sh +++ b/bin/start_service.sh @@ -42,4 +42,4 @@ source ${APP_DIR}/.venv/bin/activate # TODO: use `exec python3 ...` here? python -u -B -m agebd_${SVC_NAME_LOWER_UNDERSCORES}.main -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 diff --git a/packages/agebd/src/agebd/service/pvs.py b/packages/agebd/src/agebd/service/pvs.py index 887b92d..88db81f 100644 --- a/packages/agebd/src/agebd/service/pvs.py +++ b/packages/agebd/src/agebd/service/pvs.py @@ -1,6 +1,6 @@ from agebd.pv import PVLink -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 class BasePVs: diff --git a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py index c37cc54..8976d38 100644 --- a/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py +++ b/services/dbpm3curr/current/app/src/agebd_dbpm3curr/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_dbpm3curr import PVs, Service from agebd_dbpm3curr.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/injectionguard/current/app/src/agebd_injectionguard/main.py b/services/injectionguard/current/app/src/agebd_injectionguard/main.py index e0f95c5..4be6b36 100644 --- a/services/injectionguard/current/app/src/agebd_injectionguard/main.py +++ b/services/injectionguard/current/app/src/agebd_injectionguard/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_injectionguard import PVs, Service from agebd_injectionguard.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/master/current/app/src/agebd_master/main.py b/services/master/current/app/src/agebd_master/main.py index 141d067..562c65d 100644 --- a/services/master/current/app/src/agebd_master/main.py +++ b/services/master/current/app/src/agebd_master/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_master import PVs, Service from agebd_master.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/plots/current/app/src/agebd_plots/main.py b/services/plots/current/app/src/agebd_plots/main.py index 32b23bf..34f4e6e 100644 --- a/services/plots/current/app/src/agebd_plots/main.py +++ b/services/plots/current/app/src/agebd_plots/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_plots import PVs, Service from agebd_plots.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py index 24b5c00..74b1b1b 100644 --- a/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py +++ b/services/postmortemlog/current/app/src/agebd_postmortemlog/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_postmortemlog import PVs, Service from agebd_postmortemlog.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/scrubbing/current/app/src/agebd_scrubbing/main.py b/services/scrubbing/current/app/src/agebd_scrubbing/main.py index f9e95ab..7a81b9d 100644 --- a/services/scrubbing/current/app/src/agebd_scrubbing/main.py +++ b/services/scrubbing/current/app/src/agebd_scrubbing/main.py @@ -6,7 +6,7 @@ from agebd_scrubbing import PVs, Service from agebd_scrubbing.runner import Runner from agebd_scrubbing.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/shifttool/current/app/src/agebd_shifttool/main.py b/services/shifttool/current/app/src/agebd_shifttool/main.py index 82a4d08..cba0182 100644 --- a/services/shifttool/current/app/src/agebd_shifttool/main.py +++ b/services/shifttool/current/app/src/agebd_shifttool/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_shifttool import PVs, Service from agebd_shifttool.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/taubpm/current/app/src/agebd_taubpm/main.py b/services/taubpm/current/app/src/agebd_taubpm/main.py index 2b19800..41a617f 100644 --- a/services/taubpm/current/app/src/agebd_taubpm/main.py +++ b/services/taubpm/current/app/src/agebd_taubpm/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taubpm import PVs, Service from agebd_taubpm.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/taupct/current/app/src/agebd_taupct/main.py b/services/taupct/current/app/src/agebd_taupct/main.py index b4001a1..bae3362 100644 --- a/services/taupct/current/app/src/agebd_taupct/main.py +++ b/services/taupct/current/app/src/agebd_taupct/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_taupct import PVs, Service from agebd_taupct.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/timing/current/app/src/agebd_timing/main.py b/services/timing/current/app/src/agebd_timing/main.py index c3fe8dc..108a8ad 100644 --- a/services/timing/current/app/src/agebd_timing/main.py +++ b/services/timing/current/app/src/agebd_timing/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_timing import PVs, Service from agebd_timing.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/topuptool/current/app/src/agebd_topuptool/main.py b/services/topuptool/current/app/src/agebd_topuptool/main.py index 4be29be..9411ce4 100644 --- a/services/topuptool/current/app/src/agebd_topuptool/main.py +++ b/services/topuptool/current/app/src/agebd_topuptool/main.py @@ -6,7 +6,7 @@ from agebd_topuptool import PVs, Service from agebd_topuptool.runner import Runner from agebd_topuptool.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/tune/current/app/src/agebd_tune/main.py b/services/tune/current/app/src/agebd_tune/main.py index f4b8e8a..4ac9a8c 100644 --- a/services/tune/current/app/src/agebd_tune/main.py +++ b/services/tune/current/app/src/agebd_tune/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tune import PVs, Service from agebd_tune.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/tunebump/current/app/src/agebd_tunebump/main.py b/services/tunebump/current/app/src/agebd_tunebump/main.py index 0750964..0796a71 100644 --- a/services/tunebump/current/app/src/agebd_tunebump/main.py +++ b/services/tunebump/current/app/src/agebd_tunebump/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunebump import PVs, Service from agebd_tunebump.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/tunefbx/current/app/src/agebd_tunefbx/main.py b/services/tunefbx/current/app/src/agebd_tunefbx/main.py index fb3a0c9..6fb3e8a 100644 --- a/services/tunefbx/current/app/src/agebd_tunefbx/main.py +++ b/services/tunefbx/current/app/src/agebd_tunefbx/main.py @@ -6,7 +6,7 @@ from agebd.utils import init_logging from agebd_tunefbx import PVs, Service from agebd_tunefbx.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( diff --git a/services/tunefby/current/app/src/agebd_tunefby/main.py b/services/tunefby/current/app/src/agebd_tunefby/main.py index 5545f7f..42f00cc 100644 --- a/services/tunefby/current/app/src/agebd_tunefby/main.py +++ b/services/tunefby/current/app/src/agebd_tunefby/main.py @@ -7,7 +7,7 @@ from agebd_tunefby import PVs, Service from agebd_tunefby.service import SERVICE_NAME -# TODO: remove: cicd test 10 +# TODO: remove: cicd test 26 def main( log_level: LogLevel = typer.Option(