Compare commits

...

18 Commits
v0.0.1 ... main

Author SHA1 Message Date
933c488444 try using a fixed hash
All checks were successful
Python package / lint (push) Successful in -17s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in -15s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been skipped
2024-12-08 13:46:21 -07:00
0242b4f541 Use same version of pypa/gh-action-pypi-publish as was used to upload v0.1.0
Some checks failed
Python package / lint (push) Successful in -18s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in -16s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Failing after -23s
2024-12-08 13:44:02 -07:00
0954c2322a Merge branch 'truncation'
Some checks failed
Python package / lint (push) Successful in -17s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in -16s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Failing after -21s
Fixes #1
2024-12-08 13:26:59 -07:00
8c1e9751af Fix truncation warning 2024-12-08 13:26:25 -07:00
da2c453430 Don't publish to testpypi
All checks were successful
Python package / lint (push) Successful in 11s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 10s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been skipped
2024-10-20 23:58:08 -06:00
2668a880ee formatting
Some checks failed
Python package / lint (push) Successful in 7s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 8s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been skipped
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Failing after 3s
2024-09-14 23:05:50 -06:00
5891409fdb print real time
All checks were successful
Python package / lint (push) Successful in 6s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 8s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Successful in 5s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Successful in 5s
2024-09-14 18:32:39 -06:00
0e9eba4900 add dry-run 2024-09-14 17:59:49 -06:00
e02737abd1 fix behavior with infinite retries
All checks were successful
Python package / lint (push) Successful in 7s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 9s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Successful in 5s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Successful in 4s
2024-09-14 17:50:59 -06:00
4671cf5fac get rid of default config path 2024-09-14 17:46:39 -06:00
88a751c590 relock
Some checks failed
Python package / lint (push) Successful in 6s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 8s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been skipped
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Failing after 3s
2024-09-14 17:43:18 -06:00
e434173dfb pylance 2024-09-14 17:39:48 -06:00
e677309631 only retry on failure
Some checks failed
Python package / lint (push) Successful in 7s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 9s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been skipped
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Failing after 2s
2024-09-14 17:35:46 -06:00
69505e8371 disable signing
Some checks failed
Python package / lint (push) Successful in 7s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 9s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Has been skipped
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Failing after 2s
2024-09-14 17:32:39 -06:00
a5b7c0220b allow earlier python versions
Some checks failed
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 8s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Successful in 5s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Successful in 4s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release (push) Failing after 13s
Python package / lint (push) Successful in 6s
2024-09-14 17:31:23 -06:00
1c1eaa71de ignore _version.py
Some checks failed
Python package / lint (push) Successful in 6s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Build distribution 📦 (push) Successful in 8s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to PyPI (push) Successful in 5s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release (push) Failing after 17s
Publish Python 🐍 distribution 📦 to PyPI and TestPyPI / Publish Python 🐍 distribution 📦 to TestPyPI (push) Successful in 4s
2024-09-14 17:21:21 -06:00
30f0d0a576 improve template _version.py 2024-09-14 17:20:14 -06:00
e2e19876cc fix pypi token 2024-09-14 17:16:19 -06:00
7 changed files with 132 additions and 108 deletions

View File

@ -55,80 +55,82 @@ jobs:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
github-release:
name: >-
Sign the Python 🐍 distribution 📦 with Sigstore
and upload them to GitHub Release
needs:
- publish-to-pypi
runs-on: ubuntu-latest
permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for sigstore
env:
RUNNER_TOOL_CACHE: /toolcache # https://about.gitea.com/resources/tutorials/enable-gitea-actions-cache-to-accelerate-cicd
AGENT_TOOLSDIRECTORY: /toolcache # https://github.com/actions/setup-python/issues/824
steps:
- name: Download all the dists
uses: actions/download-artifact@v3
uses: pypa/gh-action-pypi-publish@0ab0b79471669eb3a4d647e625009c62f9f3b241
with:
name: python-package-distributions
path: dist/
- name: Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v2.1.1
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
'${{ github.ref_name }}'
--repo '${{ github.repository }}'
--notes ""
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `dist/` contains the built packages, and the
# sigstore-produced signatures and certificates.
run: >-
gh release upload
'${{ github.ref_name }}' dist/**
--repo '${{ github.repository }}'
password: ${{ secrets.PYPI_API_TOKEN }}
publish-to-testpypi:
name: Publish Python 🐍 distribution 📦 to TestPyPI
needs:
- build
runs-on: ubuntu-latest
# github-release:
# name: >-
# Sign the Python 🐍 distribution 📦 with Sigstore
# and upload them to GitHub Release
# needs:
# - publish-to-pypi
# runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/goat_monitor
# permissions:
# contents: write # IMPORTANT: mandatory for making GitHub Releases
# id-token: write # IMPORTANT: mandatory for sigstore
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing
# env:
# RUNNER_TOOL_CACHE: /toolcache # https://about.gitea.com/resources/tutorials/enable-gitea-actions-cache-to-accelerate-cicd
# AGENT_TOOLSDIRECTORY: /toolcache # https://github.com/actions/setup-python/issues/824
env:
RUNNER_TOOL_CACHE: /toolcache # https://about.gitea.com/resources/tutorials/enable-gitea-actions-cache-to-accelerate-cicd
AGENT_TOOLSDIRECTORY: /toolcache # https://github.com/actions/setup-python/issues/824
# steps:
# - name: Download all the dists
# uses: actions/download-artifact@v3
# with:
# name: python-package-distributions
# path: dist/
# - name: Sign the dists with Sigstore
# uses: sigstore/gh-action-sigstore-python@v2.1.1
# with:
# inputs: >-
# ./dist/*.tar.gz
# ./dist/*.whl
# - name: Create GitHub Release
# env:
# GITHUB_TOKEN: ${{ github.token }}
# run: >-
# gh release create
# '${{ github.ref_name }}'
# --repo '${{ github.repository }}'
# --notes ""
# - name: Upload artifact signatures to GitHub Release
# env:
# GITHUB_TOKEN: ${{ github.token }}
# # Upload to GitHub Release using the `gh` CLI.
# # `dist/` contains the built packages, and the
# # sigstore-produced signatures and certificates.
# run: >-
# gh release upload
# '${{ github.ref_name }}' dist/**
# --repo '${{ github.repository }}'
steps:
- name: Download all the dists
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
# publish-to-testpypi:
# name: Publish Python 🐍 distribution 📦 to TestPyPI
# needs:
# - build
# runs-on: ubuntu-latest
# environment:
# name: testpypi
# url: https://test.pypi.org/p/goat_monitor
# permissions:
# id-token: write # IMPORTANT: mandatory for trusted publishing
# env:
# RUNNER_TOOL_CACHE: /toolcache # https://about.gitea.com/resources/tutorials/enable-gitea-actions-cache-to-accelerate-cicd
# AGENT_TOOLSDIRECTORY: /toolcache # https://github.com/actions/setup-python/issues/824
# steps:
# - name: Download all the dists
# uses: actions/download-artifact@v3
# with:
# name: python-package-distributions
# path: dist/
# - name: Publish distribution 📦 to TestPyPI
# uses: pypa/gh-action-pypi-publish@release/v1
# with:
# password: ${{ secrets.TEST_PYPI_API_TOKEN }}
# repository-url: https://test.pypi.org/legacy/

4
.gitignore vendored
View File

@ -159,4 +159,6 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
#.idea/
**/_version.py

10
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "13a000de8cd5f6c3d270d059f8df15653008a32b9daa31494cc26bd4c80dd8d0"
"sha256": "4c61c72e95ca800fd43f3c1ba0fdbb9d0b96e8684edff51ae5c2f74a693ac20e"
},
"pipfile-spec": 6,
"requires": {
@ -37,16 +37,18 @@
"sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==8.1.7"
},
"goat-monitor": {
"editable": true,
"file": "."
},
"gotify": {
"hashes": [
"sha256:184faec76de78279c5acd6e21dfefd11223d74a816b607f1063ac22df40641b2",
"sha256:47bdc0332143cd5c251e284ffa487467429c624a1d40aefb013774f6f4dd4b7d"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==0.6.0"
},
@ -138,7 +140,6 @@
"sha256:fac6e277a41163d27dfab5f4ec1f7a83fac94e170665a4a50191b545721c6521",
"sha256:fcd8f556cdc8cfe35e70efb92463082b7f43dd7e547eb071ffc36abc0ca4699b"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==2.1.1"
},
@ -155,7 +156,6 @@
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
],
"index": "pypi",
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.2"
}

View File

@ -6,16 +6,17 @@ Yes, I know Gotify doesn't have "goat" in its name but it sounds like it.
## Configuration
Configuration lives in a TOML file which should have (at a minimum) the following:
```toml
server = "https://gotify.example.com"
app_token = "app_token_from_gotify"
```
## Usage
```
goat_monitor --config ./config.toml --retries -1 -- <COMMAND TO MONITOR>
goat_monitor --config ./config.toml --retries 3 -- <COMMAND TO MONITOR>
```
The command can be any shell command including arbitrarily many options / arguments.

View File

@ -1 +0,0 @@
__version__ = "editable"

View File

@ -9,7 +9,7 @@ import gotify
import numpy as np
import toml
from goat_monitor._version import __version__
from goat_monitor._version import __version__ # type: ignore
# %% commands
@ -17,7 +17,8 @@ from goat_monitor._version import __version__
@click.argument("command", nargs=-1, required=False, type=str)
@click.option(
"--config",
default="~/.config/goat_monitor.toml",
# default="~/.config/goat_monitor.toml",
required=True,
type=click.Path(path_type=Path),
help="Use a .toml configuration file",
)
@ -33,7 +34,13 @@ from goat_monitor._version import __version__
default=False,
help="Print version and exit",
)
def wrap(command: List[str], config: Path, retries: int, version):
@click.option(
"--dry-run",
is_flag=True,
default=False,
help="Run command without sending any notifications",
)
def wrap(command: List[str], config: Path, retries: int, version: bool, dry_run: bool):
"""Wrap an arbitrary command with gotify notifications"""
if version:
@ -45,35 +52,42 @@ def wrap(command: List[str], config: Path, retries: int, version):
settings = toml.load(f)
# gotify configuration
url = settings["server"]
app_token = settings["app_token"]
with gotify.Gotify(base_url=url, app_token=app_token) as gotify_connection:
# this is just to test configuration.
# I don't know how long a gotify connection will stay up so rather than thinking about it
# I'm just creating a new one whenever I need to send a message
pass
if not dry_run:
url = settings["server"]
app_token = settings["app_token"]
with gotify.Gotify(base_url=url, app_token=app_token) as gotify_connection:
# this is just to test configuration.
# I don't know how long a gotify connection will stay up so rather than thinking about it
# I'm just creating a new one whenever I need to send a message
pass
if retries == -1:
retries = np.inf
if retries < 0:
raise ValueError("Invalid number of retries specified")
for attempt in range(retries + 1):
attempt = 0
while attempt <= retries:
# run the command
result = subprocess.run(
with subprocess.Popen(
" ".join(command),
shell=True,
stderr=subprocess.STDOUT,
stdout=subprocess.PIPE,
encoding="utf-8",
)
) as proc:
stdout = ""
while True:
c = proc.stdout.read(1)
if c == b"":
break
s = c.decode("utf-8")
stdout += s
print(s, end="", flush=True)
return_code = proc.wait()
# TODO: print lines real time as the subprocess runs
print(result.stdout, end="")
if result.returncode:
if return_code:
# failed
title = f"Command failed with exit code {result.returncode}"
title = f"Command failed with exit code {return_code}"
if attempt < retries:
title += f" - Retrying (attempt {attempt+1}/{retries})"
else:
@ -83,20 +97,26 @@ def wrap(command: List[str], config: Path, retries: int, version):
title = "Command succeeded"
MAX_LINES = 20
lines = result.stdout.splitlines()
lines = stdout.splitlines()
truncated = False
if len(lines) > MAX_LINES:
truncated = True
lines = lines[-MAX_LINES:]
message = (
"Command:\n"
+ " ".join(command)
+ f'\n\nResult{ " (truncated)" if len(lines) > MAX_LINES else ""}:\n'
+ "\n".join(lines)
"Command:\n" + " ".join(command) + f'\n\nResult{ " (truncated)" if truncated else ""}:\n' + "\n".join(lines)
)
with gotify.Gotify(base_url=url, app_token=app_token) as gotify_connection:
gotify_connection.create_message(message=message, title=title)
if not dry_run:
with gotify.Gotify(base_url=url, app_token=app_token) as gotify_connection:
gotify_connection.create_message(message=message, title=title)
sys.exit(result.returncode)
if not return_code:
# only retry on failure
break
attempt += 1
sys.exit(return_code)
# %% main

View File

@ -7,7 +7,7 @@ name = "goat_monitor"
authors = [{ name = "Brendan Haines", email = "brendan.haines@gmail.com" }]
description = "Remote monitoring of anything"
readme = "README.md"
requires-python = ">=3.11" # might work with earlier versions, I haven't tried
requires-python = ">=3"
# keywords = ["one", "two"]
license = { text = "MIT License" }
classifiers = ["Programming Language :: Python :: 3"]