Switch to automatic versioning

This commit is contained in:
Luke Tainton 2024-04-21 17:20:58 +01:00
parent 4df979ef6b
commit 618b8c149b
10 changed files with 157 additions and 31 deletions

View File

@ -1 +1,4 @@
WEBEX_API_KEY=""
APP_LIFECYCLE="dev"
SENTRY_ENABLED="False"
SENTRY_DSN=""
WEBEX_API_KEY=""

View File

@ -1,16 +1,14 @@
name: CI
on:
push:
branches: [ main ]
pull_request:
types: [opened, synchronize, reopened]
paths-ignore:
- 'README.md'
- 'LICENSE.md'
- '.gitignore'
- '.github/CODEOWNERS'
- '.github/renovate.json'
- '.github/dependabot.yml'
- "README.md"
- "LICENSE.md"
- ".gitignore"
- ".github/CODEOWNERS"
- ".github/renovate.json"
- ".github/dependabot.yml"
jobs:
pythonci:

View File

@ -1,19 +0,0 @@
name: Build
on:
push:
branches: [main]
jobs:
build:
name: GitHub Container Registry
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Login to GitHub Container Registry
run: echo ${{ secrets.GHCR_ACCESS_TOKEN }} | docker login ghcr.io -u luketainton --password-stdin
- name: Build image for GitHub Package Registry
run: docker build . --file Dockerfile --tag ghcr.io/luketainton/webexmemebot:${{ github.sha }} --tag ghcr.io/luketainton/webexmemebot:latest
- name: Push image to GitHub Package Registry
run: |
docker push ghcr.io/luketainton/webexmemebot:latest
docker push ghcr.io/luketainton/webexmemebot:${{ github.sha }}

56
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,56 @@
name: Build
on:
push:
branches: [main]
jobs:
release:
name: Release
runs-on: ubuntu-latest
outputs:
new_tag: ${{ steps.tag_version.outputs.new_tag }}
steps:
- uses: actions/checkout@v4
- name: Bump version and push tag
id: tag_version
uses: mathieudutour/github-tag-action@v6.2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
default_bump: minor
- name: Create a GitHub release
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.tag_version.outputs.new_tag }}
name: ${{ steps.tag_version.outputs.new_tag }}
body: ${{ steps.tag_version.outputs.changelog }}
publish:
name: GitHub Container Registry
runs-on: ubuntu-latest
needs: release
steps:
- uses: actions/checkout@v4
- name: Login to GitHub Container Registry
run: echo ${{ secrets.GHCR_ACCESS_TOKEN }} | docker login ghcr.io -u luketainton --password-stdin
- name: Build image for GitHub Package Registry
run: |
docker build . --file Dockerfile \
--build-arg "version=${{ needs.release.outputs.new_tag }}" \
--tag ghcr.io/luketainton/webexmemebot:${{ needs.release.outputs.new_tag }} \
--tag ghcr.io/luketainton/webexmemebot:latest
- name: Push image to GitHub Package Registry
run: |
docker push ghcr.io/luketainton/webexmemebot:latest
docker push ghcr.io/luketainton/webexmemebot:${{ needs.release.outputs.new_tag }}
deploy:
name: Update Portainer Deployment
runs-on: ubuntu-latest
needs: publish
steps:
- uses: fjogeleit/http-request-action@v1
with:
url: ${{ secrets.PORTAINER_WEBHOOK_URL }}
method: POST
timeout: 60000
preventFailureOnNoResponse: "true"

View File

@ -15,4 +15,7 @@ RUN pip install --no-cache-dir -r requirements.txt
ENTRYPOINT ["python3", "-B", "-m", "app.main"]
ARG version="dev"
ENV APP_VERSION=$version
COPY app /run/app

48
app/config.py Normal file
View File

@ -0,0 +1,48 @@
"""Configuration module."""
import os
class Config:
"""Configuration module."""
def __init__(self) -> None:
"""Configuration module."""
self.__environment: str = os.environ.get("APP_LIFECYCLE", "DEV").upper()
self.__version: str = os.environ["APP_VERSION"]
self.__webex_token: str = os.environ["WEBEX_API_KEY"]
self.__sentry_dsn: str = os.environ.get("SENTRY_DSN", "")
self.__sentry_enabled: bool = bool(
os.environ.get("SENTRY_ENABLED", "False").upper() == "TRUE"
and self.__sentry_dsn != ""
)
@property
def environment(self) -> str:
"""Returns the current app lifecycle."""
return self.__environment
@property
def version(self) -> str:
"""Returns the current app version."""
return self.__version
@property
def sentry_enabled(self) -> bool:
"""Returns True if Sentry SDK is enabled, else False."""
return self.__sentry_enabled
@property
def sentry_dsn(self) -> str:
"""Returns the Sentry DSN value if Sentry SDK is enabled AND
Sentry DSN is set, else blank string."""
if not self.__sentry_enabled:
return ""
return self.__sentry_dsn
@property
def webex_token(self) -> str:
"""Returns the Webex API key."""
return self.__webex_token
config: Config = Config()

View File

@ -1,18 +1,29 @@
#!/usr/local/bin/python3
import os
import sentry_sdk
from sentry_sdk.integrations.stdlib import StdlibIntegration
from webex_bot.webex_bot import WebexBot
from app import close, meme
from app.config import config
WBX_API_KEY: str = os.environ["WEBEX_API_KEY"]
if config.sentry_enabled:
apm = sentry_sdk.init(
dsn=config.sentry_dsn,
enable_tracing=True,
environment=config.environment,
release=config.version,
integrations=[StdlibIntegration()],
spotlight=True
)
def create_bot() -> WebexBot:
"""Create a Bot object."""
bot = WebexBot(
teams_bot_token=WBX_API_KEY,
teams_bot_token=config.webex_token,
approved_domains=["cisco.com"],
bot_name="MemeBot",
include_demo_commands=False,

View File

@ -9,6 +9,7 @@ readme = "README.md"
python = "^3.11.2"
webex-bot = "^0.4.0"
pillow = "^10.3.0"
sentry-sdk = "^1.45.0"
[tool.poetry.group.dev.dependencies]
black = "^24.4.0"

View File

@ -10,6 +10,7 @@ pyjwt==2.8.0
pyreadline3==3.4.1 ; sys_platform == "win32" and python_full_version == "3.11.2"
requests-toolbelt==1.0.0
requests==2.31.0
sentry-sdk==1.45.0
urllib3==2.2.1
webex-bot==0.4.1
webexteamssdk==1.6.1

24
tests/test_config.py Normal file
View File

@ -0,0 +1,24 @@
"""Provides test cases for app/config.py."""
import os
vars: dict = {
"APP_VERSION": "dev",
"WEBEX_API_KEY": "testing",
"SENTRY_ENABLED": "false",
"SENTRY_DSN": "http://localhost"
}
for var, value in vars.items():
os.environ[var] = value
# needs to be imported AFTER environment variables are set
from app.config import config # pragma: no cover
def test_config() -> None:
assert config.webex_token == vars["WEBEX_API_KEY"]
assert config.version == vars["APP_VERSION"]
assert config.sentry_enabled == bool(vars["SENTRY_ENABLED"].lower() == "true")