diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 20ca13d..576d26a 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -6,13 +6,37 @@ on: - main tags: - 'v*.*.*' + pull_request: permissions: contents: read packages: write jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: pip install --no-cache-dir -r requirements-dev.txt + + - name: Import smoke test (catch circular imports) + run: python -c "import hutbot, hutbot.state, hutbot.actions, hutbot.buttons, hutbot.scheduling, hutbot.routing, hutbot.commands.dispatch, hutbot.webui_backend" + + - name: Run tests + run: python -m pytest + build-and-push: + needs: test + if: github.event_name == 'push' runs-on: ubuntu-latest steps: @@ -29,11 +53,23 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + # Tag pushes (v*.*.*) publish immutable release tags only, so deployments can + # pin an exact version. Pushes to main additionally move the `main`/`latest` + # floating tags, which are for convenience only and must not be deployed. + - name: Compute image tags + id: tags + run: | + image=ghcr.io/mittwald/hutbot + if [ "$GITHUB_REF_TYPE" = "tag" ]; then + tags="$image:$GITHUB_REF_NAME,$image:${GITHUB_REF_NAME#v}" + else + tags="$image:$GITHUB_REF_NAME,$image:latest" + fi + echo "tags=$tags" >> "$GITHUB_OUTPUT" + - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . push: true - tags: | - ghcr.io/mittwald/hutbot:latest - ghcr.io/mittwald/hutbot:${{ github.ref_name }} \ No newline at end of file + tags: ${{ steps.tags.outputs.tags }} diff --git a/.gitignore b/.gitignore index 6ea8b91..4fdee46 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ employees.json .env .codex scheduled_replies.json +button_states.json +.env-dev diff --git a/Dockerfile b/Dockerfile index 4375039..3f9bfd5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,4 +8,6 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . . -ENTRYPOINT ["python", "bot.py"] +EXPOSE 8080 + +ENTRYPOINT ["python", "-m", "hutbot"] diff --git a/README.md b/README.md index 6a27b4c..d5ef24a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The hutbot is a simple Slack bot that monitors messages in a channel and automatically replies in a thread if no one reacts or responds to the message within a configurable time period (by default 30 minutes). The bot reminds channel members that a message has gone unanswered. Scheduled reminders are cancelled when someone replies in the thread or reacts in a way that does not match the config criteria that caused that reminder to be scheduled, or when the original message is deleted. Users can adjust both the waiting time and the reminder message directly within the channel, including `{{variable}}` placeholders in the reminder text. -Reply messages support built-in placeholders such as `{{user}}`, `{{channel}}`, and `{{message_link}}`. If a channel config also has an Opsgenie schedule configured via `/hutbot [config] set opsgenie-schedule `, Hutbot can resolve the current on-call person and expose: +Reply messages support built-in placeholders such as `{{user}}`, `{{channel}}`, and `{{message_link}}`. `{{date}}`, `{{time}}`, and `{{datetime}}` render the triggering message's time — or the time the rule ran, for `cron`/`manual` triggers and for `test`/`run` — using the config's date/time format, timezone, and locale, and take the same `fmt`/`tz`/`lc` arguments as the Opsgenie date/time variables below. `{{timestamp}}` is the raw Slack timestamp of the same instant. If a channel config also has an Opsgenie schedule configured via `/hutbot [config] set opsgenie-schedule `, Hutbot can resolve the current on-call person and expose: - `{{opsgenie_schedule_name}}` for the configured schedule - `{{opsgenie_current_user}}` for a Slack `@mention` @@ -22,12 +22,227 @@ Opsgenie date/time variables support `fmt`/`format`, `tz`/`timezone`, and `lc`/` /hutbot [config] set datefmt "" "