gsuite-manager 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gsuite_manager-0.3.0/.devcontainer/devcontainer.json +26 -0
- gsuite_manager-0.3.0/.editorconfig +19 -0
- gsuite_manager-0.3.0/.env.example +63 -0
- gsuite_manager-0.3.0/.git-blame-ignore-revs +8 -0
- gsuite_manager-0.3.0/.github/CODEOWNERS +15 -0
- gsuite_manager-0.3.0/.github/DISCUSSION_TEMPLATE/ideas.yml +22 -0
- gsuite_manager-0.3.0/.github/DISCUSSION_TEMPLATE/questions.yml +25 -0
- gsuite_manager-0.3.0/.github/DISCUSSION_TEMPLATE/show-and-tell.yml +15 -0
- gsuite_manager-0.3.0/.github/FUNDING.yml +1 -0
- gsuite_manager-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +66 -0
- gsuite_manager-0.3.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- gsuite_manager-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +44 -0
- gsuite_manager-0.3.0/.github/PULL_REQUEST_TEMPLATE.md +19 -0
- gsuite_manager-0.3.0/.github/dependabot.yml +21 -0
- gsuite_manager-0.3.0/.github/labeler.yml +33 -0
- gsuite_manager-0.3.0/.github/workflows/ci.yml +115 -0
- gsuite_manager-0.3.0/.github/workflows/docs.yml +46 -0
- gsuite_manager-0.3.0/.github/workflows/labeler.yml +17 -0
- gsuite_manager-0.3.0/.github/workflows/links.yml +19 -0
- gsuite_manager-0.3.0/.github/workflows/release.yml +59 -0
- gsuite_manager-0.3.0/.github/workflows/stale.yml +29 -0
- gsuite_manager-0.3.0/.gitignore +77 -0
- gsuite_manager-0.3.0/.hypothesis/.gitignore +9 -0
- gsuite_manager-0.3.0/.hypothesis/constants/02898924491dddec +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/083d763c36b0b99b +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/1804de7a2dadf5df +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/18ab21454657fcd0 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/18fb2fdac668d0e3 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/1ada8586c634c9b9 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/29e2cc3a2e9df08d +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/2fab2cbf63aef9b9 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/2ff92e719c602fc7 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/3299fa0e101f547c +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/336d9c4ca38d4149 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/3a56836b934d881c +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/3e963115302a0038 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/439aa72b228c5722 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/4afaab6adf499964 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/571810267717e369 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/57c54bbab7939b32 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/585279eee93c43a9 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/58847485ea9d843e +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/66d3a084fddf947d +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/682fe2b04dce5292 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/69e08ac59bb963f2 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/69f49c039bab4712 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/6c3c65e0402226f6 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/74f64fb72c113dcb +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/78314297c8b7f421 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/8003030ee846ab96 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/8044b4f0b7390541 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/8586aa5b90d9beac +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/9c2ced31e4a957d2 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/9e2d420cdad15313 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/9e7d3603f2a74075 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/a2d160ea3cf51b50 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/b6c4c372c8e67803 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/b714a2788e5197c3 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/b9a3943715e4fc1d +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/bea65b1a3227186f +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/c4752d9549d5e3f1 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/cb4158fd3143b538 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/cc2ccda28358debf +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/ce4bd9d0de3cdd21 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/da39a3ee5e6b4b0d +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/e1ff7f5840c7b665 +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/eb054d45d654606e +4 -0
- gsuite_manager-0.3.0/.hypothesis/constants/f2bec7ffccba40ef +4 -0
- gsuite_manager-0.3.0/.hypothesis/unicode_data/15.0.0/charmap.json.gz +0 -0
- gsuite_manager-0.3.0/.hypothesis/unicode_data/15.0.0/codec-utf-8.json.gz +0 -0
- gsuite_manager-0.3.0/.pre-commit-config.yaml +26 -0
- gsuite_manager-0.3.0/AGENTS.md +52 -0
- gsuite_manager-0.3.0/CHANGELOG.md +75 -0
- gsuite_manager-0.3.0/CODE_OF_CONDUCT.md +54 -0
- gsuite_manager-0.3.0/CONTRIBUTING.md +109 -0
- gsuite_manager-0.3.0/LICENSE +21 -0
- gsuite_manager-0.3.0/Makefile +48 -0
- gsuite_manager-0.3.0/PKG-INFO +260 -0
- gsuite_manager-0.3.0/README.md +208 -0
- gsuite_manager-0.3.0/SECURITY.md +36 -0
- gsuite_manager-0.3.0/docs/assets/logo-dark.svg +13 -0
- gsuite_manager-0.3.0/docs/assets/logo.svg +13 -0
- gsuite_manager-0.3.0/docs/assets/social-preview.png +0 -0
- gsuite_manager-0.3.0/docs/assets/terminal.svg +59 -0
- gsuite_manager-0.3.0/docs/index.md +30 -0
- gsuite_manager-0.3.0/docs/production-runbook.md +159 -0
- gsuite_manager-0.3.0/docs/publishing.md +32 -0
- gsuite_manager-0.3.0/docs/reference/cli.md +7 -0
- gsuite_manager-0.3.0/docs/reference/clients.md +15 -0
- gsuite_manager-0.3.0/docs/reference/core.md +29 -0
- gsuite_manager-0.3.0/docs/reference/models.md +15 -0
- gsuite_manager-0.3.0/docs/reference/state.md +8 -0
- gsuite_manager-0.3.0/docs/setup.md +179 -0
- gsuite_manager-0.3.0/docs/troubleshooting.md +78 -0
- gsuite_manager-0.3.0/docs/usage.md +167 -0
- gsuite_manager-0.3.0/llms.txt +20 -0
- gsuite_manager-0.3.0/mkdocs.yml +75 -0
- gsuite_manager-0.3.0/pyproject.toml +126 -0
- gsuite_manager-0.3.0/scripts/smoke_test.sh +68 -0
- gsuite_manager-0.3.0/src/gsm/__init__.py +8 -0
- gsuite_manager-0.3.0/src/gsm/__main__.py +11 -0
- gsuite_manager-0.3.0/src/gsm/cli/__init__.py +77 -0
- gsuite_manager-0.3.0/src/gsm/cli/_shared.py +236 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/__init__.py +0 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/audit.py +149 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/dns.py +132 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/doctor.py +145 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/domains.py +508 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/expiry.py +115 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/go.py +144 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/groups.py +155 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/health.py +112 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/init.py +326 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/ledger.py +60 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/menu.py +435 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/__init__.py +39 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_aliases.py +67 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_app.py +11 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_audit.py +95 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_crud.py +343 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_gen.py +211 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_helpers.py +65 -0
- gsuite_manager-0.3.0/src/gsm/cli/commands/users/_suspend.py +83 -0
- gsuite_manager-0.3.0/src/gsm/clients/__init__.py +0 -0
- gsuite_manager-0.3.0/src/gsm/clients/_decorators.py +64 -0
- gsuite_manager-0.3.0/src/gsm/clients/_google_errors.py +54 -0
- gsuite_manager-0.3.0/src/gsm/clients/cloudflare.py +268 -0
- gsuite_manager-0.3.0/src/gsm/clients/dns_check.py +113 -0
- gsuite_manager-0.3.0/src/gsm/clients/google_admin.py +305 -0
- gsuite_manager-0.3.0/src/gsm/clients/google_verify.py +80 -0
- gsuite_manager-0.3.0/src/gsm/clients/mx_check.py +377 -0
- gsuite_manager-0.3.0/src/gsm/clients/username_generator.py +299 -0
- gsuite_manager-0.3.0/src/gsm/core/__init__.py +0 -0
- gsuite_manager-0.3.0/src/gsm/core/auth.py +114 -0
- gsuite_manager-0.3.0/src/gsm/core/config.py +94 -0
- gsuite_manager-0.3.0/src/gsm/core/errors.py +107 -0
- gsuite_manager-0.3.0/src/gsm/core/logging.py +83 -0
- gsuite_manager-0.3.0/src/gsm/models/__init__.py +0 -0
- gsuite_manager-0.3.0/src/gsm/models/constants.py +21 -0
- gsuite_manager-0.3.0/src/gsm/models/domain.py +33 -0
- gsuite_manager-0.3.0/src/gsm/models/results.py +38 -0
- gsuite_manager-0.3.0/src/gsm/models/user.py +39 -0
- gsuite_manager-0.3.0/src/gsm/state/__init__.py +0 -0
- gsuite_manager-0.3.0/src/gsm/state/ledger.py +199 -0
- gsuite_manager-0.3.0/src/gsm/workflows/__init__.py +0 -0
- gsuite_manager-0.3.0/src/gsm/workflows/domain_import.py +147 -0
- gsuite_manager-0.3.0/src/gsm/workflows/domain_onboarding.py +289 -0
- gsuite_manager-0.3.0/src/gsm/workflows/user_bulk_create.py +169 -0
- gsuite_manager-0.3.0/tests/__init__.py +0 -0
- gsuite_manager-0.3.0/tests/conftest.py +71 -0
- gsuite_manager-0.3.0/tests/fixtures/sample_domains.txt +152 -0
- gsuite_manager-0.3.0/tests/test_audit.py +206 -0
- gsuite_manager-0.3.0/tests/test_auth.py +181 -0
- gsuite_manager-0.3.0/tests/test_cli.py +628 -0
- gsuite_manager-0.3.0/tests/test_cli_commands.py +711 -0
- gsuite_manager-0.3.0/tests/test_cli_integration.py +385 -0
- gsuite_manager-0.3.0/tests/test_cli_interactive.py +304 -0
- gsuite_manager-0.3.0/tests/test_cloudflare.py +271 -0
- gsuite_manager-0.3.0/tests/test_config.py +159 -0
- gsuite_manager-0.3.0/tests/test_coverage_completion.py +621 -0
- gsuite_manager-0.3.0/tests/test_dns_check.py +154 -0
- gsuite_manager-0.3.0/tests/test_domain_import.py +254 -0
- gsuite_manager-0.3.0/tests/test_errors.py +76 -0
- gsuite_manager-0.3.0/tests/test_google_clients.py +619 -0
- gsuite_manager-0.3.0/tests/test_ledger.py +196 -0
- gsuite_manager-0.3.0/tests/test_logging.py +110 -0
- gsuite_manager-0.3.0/tests/test_mx_check.py +294 -0
- gsuite_manager-0.3.0/tests/test_property.py +202 -0
- gsuite_manager-0.3.0/tests/test_username_generator.py +264 -0
- gsuite_manager-0.3.0/tests/test_workflow_domain.py +345 -0
- gsuite_manager-0.3.0/tests/test_workflow_users.py +216 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gsuite-manager",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.12",
|
|
4
|
+
"features": {
|
|
5
|
+
"ghcr.io/devcontainers/features/github-cli:1": {}
|
|
6
|
+
},
|
|
7
|
+
"postCreateCommand": "pip install -e '.[dev]' && pre-commit install",
|
|
8
|
+
"customizations": {
|
|
9
|
+
"vscode": {
|
|
10
|
+
"extensions": [
|
|
11
|
+
"charliermarsh.ruff",
|
|
12
|
+
"ms-python.mypy-type-checker",
|
|
13
|
+
"ms-python.python",
|
|
14
|
+
"tamasfe.even-better-toml"
|
|
15
|
+
],
|
|
16
|
+
"settings": {
|
|
17
|
+
"python.defaultInterpreterPath": "/usr/local/bin/python",
|
|
18
|
+
"python.testing.pytestEnabled": true,
|
|
19
|
+
"[python]": {
|
|
20
|
+
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
21
|
+
"editor.formatOnSave": true
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# https://editorconfig.org
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
indent_style = space
|
|
6
|
+
indent_size = 4
|
|
7
|
+
end_of_line = lf
|
|
8
|
+
charset = utf-8
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
insert_final_newline = true
|
|
11
|
+
|
|
12
|
+
[*.{yml,yaml,toml,json}]
|
|
13
|
+
indent_size = 2
|
|
14
|
+
|
|
15
|
+
[*.md]
|
|
16
|
+
trim_trailing_whitespace = false
|
|
17
|
+
|
|
18
|
+
[Makefile]
|
|
19
|
+
indent_style = tab
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# GSuite Manager configuration template
|
|
2
|
+
# Copy to `.env` and fill in real values. NEVER commit `.env`.
|
|
3
|
+
|
|
4
|
+
# ==============================================================================
|
|
5
|
+
# Cloudflare
|
|
6
|
+
# ==============================================================================
|
|
7
|
+
# Get token at: https://dash.cloudflare.com/profile/api-tokens
|
|
8
|
+
# Required scopes: Zone:Edit, DNS:Edit, Account:Read
|
|
9
|
+
GSM_CF_API_TOKEN=your-cloudflare-api-token-here
|
|
10
|
+
|
|
11
|
+
# Find at: https://dash.cloudflare.com -> right sidebar -> Account ID
|
|
12
|
+
GSM_CF_ACCOUNT_ID=your-cloudflare-account-id-here
|
|
13
|
+
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
# Google OAuth (Desktop App)
|
|
16
|
+
# ==============================================================================
|
|
17
|
+
# Create at: https://console.cloud.google.com -> APIs & Services -> Credentials
|
|
18
|
+
# Type: "OAuth client ID" -> "Desktop app"
|
|
19
|
+
# Download JSON, place at path below (default: ./credentials.json)
|
|
20
|
+
GSM_GOOGLE_OAUTH_CLIENT_PATH=./credentials.json
|
|
21
|
+
|
|
22
|
+
# Auto-generated after first browser login. Keep secret.
|
|
23
|
+
GSM_GOOGLE_OAUTH_TOKEN_PATH=./token.json
|
|
24
|
+
|
|
25
|
+
# ==============================================================================
|
|
26
|
+
# Behavior tuning (defaults are conservative)
|
|
27
|
+
# ==============================================================================
|
|
28
|
+
# Delay between processing each domain (anti rate-limit)
|
|
29
|
+
GSM_DELAY_PER_DOMAIN_SEC=3.0
|
|
30
|
+
|
|
31
|
+
# Delay between processing each user
|
|
32
|
+
GSM_DELAY_PER_USER_SEC=1.0
|
|
33
|
+
|
|
34
|
+
# ==============================================================================
|
|
35
|
+
# DNS propagation check
|
|
36
|
+
# ==============================================================================
|
|
37
|
+
# Public resolvers used to verify TXT propagation before calling Google verify.
|
|
38
|
+
# Comma-separated. Default: Google + Cloudflare public resolvers.
|
|
39
|
+
GSM_DNS_CHECK_RESOLVERS=["8.8.8.8","1.1.1.1"]
|
|
40
|
+
|
|
41
|
+
# DNS query timeout per resolver
|
|
42
|
+
GSM_DNS_CHECK_TIMEOUT_SEC=5.0
|
|
43
|
+
|
|
44
|
+
# Max attempts to wait for DNS propagation before giving up
|
|
45
|
+
GSM_DNS_CHECK_MAX_ATTEMPTS=6
|
|
46
|
+
|
|
47
|
+
# Backoff schedule (seconds) between propagation attempts
|
|
48
|
+
GSM_DNS_CHECK_BACKOFF_SEC=[10,20,30,60,120,180]
|
|
49
|
+
|
|
50
|
+
# ==============================================================================
|
|
51
|
+
# State / ledger
|
|
52
|
+
# ==============================================================================
|
|
53
|
+
# JSON file tracking progress for idempotent re-runs
|
|
54
|
+
GSM_LEDGER_PATH=./gsm_state.json
|
|
55
|
+
|
|
56
|
+
# ==============================================================================
|
|
57
|
+
# Logging
|
|
58
|
+
# ==============================================================================
|
|
59
|
+
# Levels: DEBUG, INFO, WARNING, ERROR
|
|
60
|
+
GSM_LOG_LEVEL=INFO
|
|
61
|
+
|
|
62
|
+
# Format: console (pretty, for TTY) or json (structured, for piping/CI)
|
|
63
|
+
GSM_LOG_FORMAT=console
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Commits that are pure formatting/refactoring — ignore in git blame
|
|
2
|
+
# Usage: git config blame.ignoreRevsFile .git-blame-ignore-revs
|
|
3
|
+
|
|
4
|
+
# SSS-tier GitHub infrastructure (templates, badges, docs)
|
|
5
|
+
4a07061
|
|
6
|
+
|
|
7
|
+
# Source code refactor (users module split, retry logic, error handling)
|
|
8
|
+
88130d1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
title: "Ideas & Feature Requests"
|
|
2
|
+
labels: ["idea"]
|
|
3
|
+
body:
|
|
4
|
+
- type: markdown
|
|
5
|
+
attributes:
|
|
6
|
+
value: |
|
|
7
|
+
Share ideas for new features or improvements.
|
|
8
|
+
For bug reports, please use [Issues](https://github.com/nopperabbo/gsuite-manager/issues/new?template=bug_report.yml).
|
|
9
|
+
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: idea
|
|
12
|
+
attributes:
|
|
13
|
+
label: Describe your idea
|
|
14
|
+
description: What would you like to see in gsuite-manager?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: use-case
|
|
20
|
+
attributes:
|
|
21
|
+
label: Use case
|
|
22
|
+
description: How would this help your workflow?
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
title: "Questions & Help"
|
|
2
|
+
labels: ["question"]
|
|
3
|
+
body:
|
|
4
|
+
- type: markdown
|
|
5
|
+
attributes:
|
|
6
|
+
value: |
|
|
7
|
+
## Before asking
|
|
8
|
+
|
|
9
|
+
- Check the [Usage Guide](https://github.com/nopperabbo/gsuite-manager/blob/main/docs/USAGE.md)
|
|
10
|
+
- Check [existing discussions](https://github.com/nopperabbo/gsuite-manager/discussions)
|
|
11
|
+
- Check [closed issues](https://github.com/nopperabbo/gsuite-manager/issues?q=is%3Aissue+is%3Aclosed)
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: question
|
|
15
|
+
attributes:
|
|
16
|
+
label: Your question
|
|
17
|
+
description: What do you need help with?
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: context
|
|
23
|
+
attributes:
|
|
24
|
+
label: Context
|
|
25
|
+
description: What are you trying to accomplish? What have you tried?
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
title: "Show & Tell"
|
|
2
|
+
labels: ["showcase"]
|
|
3
|
+
body:
|
|
4
|
+
- type: markdown
|
|
5
|
+
attributes:
|
|
6
|
+
value: |
|
|
7
|
+
Share how you're using gsuite-manager! Screenshots, scripts, workflows — anything goes.
|
|
8
|
+
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: showcase
|
|
11
|
+
attributes:
|
|
12
|
+
label: What did you build?
|
|
13
|
+
description: Share your setup, workflow, or integration
|
|
14
|
+
validations:
|
|
15
|
+
required: true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: [nopperabbo]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug or unexpected behavior
|
|
3
|
+
labels: ["bug", "triage"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for reporting! Please fill in the details below.
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: description
|
|
11
|
+
attributes:
|
|
12
|
+
label: What happened?
|
|
13
|
+
description: Clear description of the bug
|
|
14
|
+
placeholder: "When I do X, Y happens instead of Z"
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: steps
|
|
19
|
+
attributes:
|
|
20
|
+
label: Steps to reproduce
|
|
21
|
+
description: Minimal steps to reproduce
|
|
22
|
+
placeholder: |
|
|
23
|
+
1. Run `gsm ...`
|
|
24
|
+
2. See error
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: expected
|
|
29
|
+
attributes:
|
|
30
|
+
label: Expected behavior
|
|
31
|
+
description: What should have happened
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
- type: input
|
|
35
|
+
id: version
|
|
36
|
+
attributes:
|
|
37
|
+
label: gsm version
|
|
38
|
+
description: Output of `gsm --version`
|
|
39
|
+
placeholder: "0.1.0"
|
|
40
|
+
validations:
|
|
41
|
+
required: true
|
|
42
|
+
- type: dropdown
|
|
43
|
+
id: os
|
|
44
|
+
attributes:
|
|
45
|
+
label: Operating System
|
|
46
|
+
options:
|
|
47
|
+
- macOS
|
|
48
|
+
- Linux (Ubuntu/Debian)
|
|
49
|
+
- Linux (Other)
|
|
50
|
+
- Windows
|
|
51
|
+
validations:
|
|
52
|
+
required: true
|
|
53
|
+
- type: input
|
|
54
|
+
id: python-version
|
|
55
|
+
attributes:
|
|
56
|
+
label: Python version
|
|
57
|
+
description: Output of `python --version`
|
|
58
|
+
placeholder: "3.12.1"
|
|
59
|
+
validations:
|
|
60
|
+
required: true
|
|
61
|
+
- type: textarea
|
|
62
|
+
id: logs
|
|
63
|
+
attributes:
|
|
64
|
+
label: Relevant logs / error output
|
|
65
|
+
description: Paste any relevant log output
|
|
66
|
+
render: shell
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Questions & Discussion
|
|
4
|
+
url: https://github.com/nopperabbo/gsuite-manager/discussions
|
|
5
|
+
about: Ask questions and discuss ideas here
|
|
6
|
+
- name: Security Vulnerability
|
|
7
|
+
url: https://github.com/nopperabbo/gsuite-manager/blob/main/SECURITY.md
|
|
8
|
+
about: Report security vulnerabilities privately
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature or improvement
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for suggesting an improvement! Please describe your idea below.
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: problem
|
|
11
|
+
attributes:
|
|
12
|
+
label: Problem / Use case
|
|
13
|
+
description: What are you trying to do that gsm doesn't support yet?
|
|
14
|
+
placeholder: "I want to be able to..."
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: solution
|
|
19
|
+
attributes:
|
|
20
|
+
label: Proposed solution
|
|
21
|
+
description: How should it work? Include command examples if possible.
|
|
22
|
+
placeholder: |
|
|
23
|
+
```bash
|
|
24
|
+
gsm new-command --flag value
|
|
25
|
+
```
|
|
26
|
+
Expected output: ...
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: alternatives
|
|
31
|
+
attributes:
|
|
32
|
+
label: Alternatives considered
|
|
33
|
+
description: Any workarounds you've tried or other approaches you considered
|
|
34
|
+
- type: dropdown
|
|
35
|
+
id: scope
|
|
36
|
+
attributes:
|
|
37
|
+
label: Scope
|
|
38
|
+
description: How big is this change?
|
|
39
|
+
options:
|
|
40
|
+
- Small (single command/flag)
|
|
41
|
+
- Medium (new subcommand)
|
|
42
|
+
- Large (new module/workflow)
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## What
|
|
2
|
+
|
|
3
|
+
<!-- One sentence: what does this PR do? -->
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
<!-- Context: what problem does this solve? Link issue if applicable. -->
|
|
8
|
+
|
|
9
|
+
## How
|
|
10
|
+
|
|
11
|
+
<!-- Brief technical approach -->
|
|
12
|
+
|
|
13
|
+
## Checklist
|
|
14
|
+
|
|
15
|
+
- [ ] Tests added/updated
|
|
16
|
+
- [ ] `pytest && ruff check src tests && mypy src` passes
|
|
17
|
+
- [ ] CHANGELOG.md updated
|
|
18
|
+
- [ ] No new dependencies without discussion
|
|
19
|
+
- [ ] Commit messages follow conventional format (`feat(scope): description`)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
labels:
|
|
8
|
+
- "dependencies"
|
|
9
|
+
commit-message:
|
|
10
|
+
prefix: "chore(deps)"
|
|
11
|
+
open-pull-requests-limit: 5
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "github-actions"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
labels:
|
|
18
|
+
- "ci"
|
|
19
|
+
commit-message:
|
|
20
|
+
prefix: "chore(ci)"
|
|
21
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
labels:
|
|
2
|
+
# Type labels
|
|
3
|
+
- label: "bug"
|
|
4
|
+
color: "d73a4a"
|
|
5
|
+
description: "Something isn't working"
|
|
6
|
+
- label: "feature"
|
|
7
|
+
color: "a2eeef"
|
|
8
|
+
description: "New feature or request"
|
|
9
|
+
- label: "docs"
|
|
10
|
+
color: "0075ca"
|
|
11
|
+
description: "Documentation improvements"
|
|
12
|
+
- label: "chore"
|
|
13
|
+
color: "e4e669"
|
|
14
|
+
description: "Maintenance and tooling"
|
|
15
|
+
- label: "good first issue"
|
|
16
|
+
color: "7057ff"
|
|
17
|
+
description: "Good for newcomers"
|
|
18
|
+
|
|
19
|
+
# Path-based auto-labeling
|
|
20
|
+
"src/gsm/cli/**":
|
|
21
|
+
- cli
|
|
22
|
+
"src/gsm/clients/**":
|
|
23
|
+
- api-clients
|
|
24
|
+
"src/gsm/core/**":
|
|
25
|
+
- core
|
|
26
|
+
"src/gsm/workflows/**":
|
|
27
|
+
- workflows
|
|
28
|
+
"tests/**":
|
|
29
|
+
- tests
|
|
30
|
+
"docs/**":
|
|
31
|
+
- docs
|
|
32
|
+
".github/**":
|
|
33
|
+
- ci/cd
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
env:
|
|
14
|
+
NO_COLOR: "1"
|
|
15
|
+
FORCE_COLOR: "0"
|
|
16
|
+
TERM: "dumb"
|
|
17
|
+
COLUMNS: "200"
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
lint:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
24
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
- name: Install
|
|
28
|
+
run: pip install -e ".[dev]"
|
|
29
|
+
- name: Ruff check
|
|
30
|
+
run: ruff check src/ tests/
|
|
31
|
+
- name: Ruff format check
|
|
32
|
+
run: ruff format --check src/ tests/
|
|
33
|
+
|
|
34
|
+
typecheck:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
38
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.12"
|
|
41
|
+
- name: Install
|
|
42
|
+
run: pip install -e ".[dev]"
|
|
43
|
+
- name: Mypy
|
|
44
|
+
run: mypy
|
|
45
|
+
|
|
46
|
+
test:
|
|
47
|
+
runs-on: ${{ matrix.os }}
|
|
48
|
+
strategy:
|
|
49
|
+
fail-fast: false
|
|
50
|
+
matrix:
|
|
51
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
52
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
55
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
56
|
+
with:
|
|
57
|
+
python-version: ${{ matrix.python-version }}
|
|
58
|
+
- name: Install
|
|
59
|
+
run: pip install -e ".[dev]"
|
|
60
|
+
- name: Test
|
|
61
|
+
run: pytest --no-cov -q
|
|
62
|
+
|
|
63
|
+
coverage:
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
67
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
68
|
+
with:
|
|
69
|
+
python-version: "3.12"
|
|
70
|
+
- name: Install
|
|
71
|
+
run: pip install -e ".[dev]"
|
|
72
|
+
- name: Test with coverage
|
|
73
|
+
run: pytest --cov=src/gsm --cov-report=xml --cov-fail-under=70
|
|
74
|
+
- name: Upload coverage
|
|
75
|
+
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
|
|
76
|
+
with:
|
|
77
|
+
file: coverage.xml
|
|
78
|
+
fail_ci_if_error: false
|
|
79
|
+
|
|
80
|
+
security:
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
84
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
85
|
+
with:
|
|
86
|
+
python-version: "3.12"
|
|
87
|
+
- name: Install
|
|
88
|
+
run: pip install -e ".[dev]" pip-audit
|
|
89
|
+
- name: Audit dependencies
|
|
90
|
+
run: pip-audit
|
|
91
|
+
|
|
92
|
+
smoke:
|
|
93
|
+
runs-on: ubuntu-latest
|
|
94
|
+
needs: [test]
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
97
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
98
|
+
with:
|
|
99
|
+
python-version: "3.12"
|
|
100
|
+
- name: Build wheel
|
|
101
|
+
run: pip install build && python -m build
|
|
102
|
+
- name: Install from wheel
|
|
103
|
+
run: pip install dist/*.whl
|
|
104
|
+
- name: Smoke test
|
|
105
|
+
run: gsm --help
|
|
106
|
+
|
|
107
|
+
alls-green:
|
|
108
|
+
if: always()
|
|
109
|
+
needs: [lint, typecheck, test, coverage, security, smoke]
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
steps:
|
|
112
|
+
- name: Decide whether all jobs passed
|
|
113
|
+
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
|
|
114
|
+
with:
|
|
115
|
+
jobs: ${{ toJSON(needs) }}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
- "mkdocs.yml"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
pages: write
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: pages
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
deploy:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
environment:
|
|
24
|
+
name: github-pages
|
|
25
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
28
|
+
with:
|
|
29
|
+
fetch-depth: 0
|
|
30
|
+
|
|
31
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.12"
|
|
34
|
+
|
|
35
|
+
- name: Install MkDocs
|
|
36
|
+
run: pip install mkdocs-material mkdocstrings[python]
|
|
37
|
+
|
|
38
|
+
- name: Build docs
|
|
39
|
+
run: mkdocs build
|
|
40
|
+
|
|
41
|
+
- uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
|
|
42
|
+
with:
|
|
43
|
+
path: site
|
|
44
|
+
|
|
45
|
+
- id: deployment
|
|
46
|
+
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Label PRs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
pull-requests: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
label:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa83b30bea # v5.0.0
|
|
16
|
+
with:
|
|
17
|
+
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: Check Links
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths: ["**/*.md"]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths: ["**/*.md"]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
links:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
15
|
+
|
|
16
|
+
- uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
|
|
17
|
+
with:
|
|
18
|
+
args: --no-progress --exclude-mail '**/*.md'
|
|
19
|
+
fail: true
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: release
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
id-token: write
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install -e ".[dev]"
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: pytest -q
|
|
34
|
+
|
|
35
|
+
- name: Build package
|
|
36
|
+
run: |
|
|
37
|
+
pip install build
|
|
38
|
+
python -m build
|
|
39
|
+
|
|
40
|
+
- name: Extract changelog for this version
|
|
41
|
+
id: changelog
|
|
42
|
+
run: |
|
|
43
|
+
VERSION=${GITHUB_REF_NAME#v}
|
|
44
|
+
awk "/^## \[${VERSION}\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md > release_notes.md
|
|
45
|
+
echo "Found release notes for v${VERSION}"
|
|
46
|
+
|
|
47
|
+
- name: Publish to PyPI
|
|
48
|
+
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
|
|
49
|
+
with:
|
|
50
|
+
attestations: true
|
|
51
|
+
|
|
52
|
+
- name: Create GitHub Release
|
|
53
|
+
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
|
|
54
|
+
with:
|
|
55
|
+
body_path: release_notes.md
|
|
56
|
+
files: dist/*
|
|
57
|
+
generate_release_notes: false
|
|
58
|
+
env:
|
|
59
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|