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.
Files changed (171) hide show
  1. gsuite_manager-0.3.0/.devcontainer/devcontainer.json +26 -0
  2. gsuite_manager-0.3.0/.editorconfig +19 -0
  3. gsuite_manager-0.3.0/.env.example +63 -0
  4. gsuite_manager-0.3.0/.git-blame-ignore-revs +8 -0
  5. gsuite_manager-0.3.0/.github/CODEOWNERS +15 -0
  6. gsuite_manager-0.3.0/.github/DISCUSSION_TEMPLATE/ideas.yml +22 -0
  7. gsuite_manager-0.3.0/.github/DISCUSSION_TEMPLATE/questions.yml +25 -0
  8. gsuite_manager-0.3.0/.github/DISCUSSION_TEMPLATE/show-and-tell.yml +15 -0
  9. gsuite_manager-0.3.0/.github/FUNDING.yml +1 -0
  10. gsuite_manager-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +66 -0
  11. gsuite_manager-0.3.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  12. gsuite_manager-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +44 -0
  13. gsuite_manager-0.3.0/.github/PULL_REQUEST_TEMPLATE.md +19 -0
  14. gsuite_manager-0.3.0/.github/dependabot.yml +21 -0
  15. gsuite_manager-0.3.0/.github/labeler.yml +33 -0
  16. gsuite_manager-0.3.0/.github/workflows/ci.yml +115 -0
  17. gsuite_manager-0.3.0/.github/workflows/docs.yml +46 -0
  18. gsuite_manager-0.3.0/.github/workflows/labeler.yml +17 -0
  19. gsuite_manager-0.3.0/.github/workflows/links.yml +19 -0
  20. gsuite_manager-0.3.0/.github/workflows/release.yml +59 -0
  21. gsuite_manager-0.3.0/.github/workflows/stale.yml +29 -0
  22. gsuite_manager-0.3.0/.gitignore +77 -0
  23. gsuite_manager-0.3.0/.hypothesis/.gitignore +9 -0
  24. gsuite_manager-0.3.0/.hypothesis/constants/02898924491dddec +4 -0
  25. gsuite_manager-0.3.0/.hypothesis/constants/083d763c36b0b99b +4 -0
  26. gsuite_manager-0.3.0/.hypothesis/constants/1804de7a2dadf5df +4 -0
  27. gsuite_manager-0.3.0/.hypothesis/constants/18ab21454657fcd0 +4 -0
  28. gsuite_manager-0.3.0/.hypothesis/constants/18fb2fdac668d0e3 +4 -0
  29. gsuite_manager-0.3.0/.hypothesis/constants/1ada8586c634c9b9 +4 -0
  30. gsuite_manager-0.3.0/.hypothesis/constants/29e2cc3a2e9df08d +4 -0
  31. gsuite_manager-0.3.0/.hypothesis/constants/2fab2cbf63aef9b9 +4 -0
  32. gsuite_manager-0.3.0/.hypothesis/constants/2ff92e719c602fc7 +4 -0
  33. gsuite_manager-0.3.0/.hypothesis/constants/3299fa0e101f547c +4 -0
  34. gsuite_manager-0.3.0/.hypothesis/constants/336d9c4ca38d4149 +4 -0
  35. gsuite_manager-0.3.0/.hypothesis/constants/3a56836b934d881c +4 -0
  36. gsuite_manager-0.3.0/.hypothesis/constants/3e963115302a0038 +4 -0
  37. gsuite_manager-0.3.0/.hypothesis/constants/439aa72b228c5722 +4 -0
  38. gsuite_manager-0.3.0/.hypothesis/constants/4afaab6adf499964 +4 -0
  39. gsuite_manager-0.3.0/.hypothesis/constants/571810267717e369 +4 -0
  40. gsuite_manager-0.3.0/.hypothesis/constants/57c54bbab7939b32 +4 -0
  41. gsuite_manager-0.3.0/.hypothesis/constants/585279eee93c43a9 +4 -0
  42. gsuite_manager-0.3.0/.hypothesis/constants/58847485ea9d843e +4 -0
  43. gsuite_manager-0.3.0/.hypothesis/constants/66d3a084fddf947d +4 -0
  44. gsuite_manager-0.3.0/.hypothesis/constants/682fe2b04dce5292 +4 -0
  45. gsuite_manager-0.3.0/.hypothesis/constants/69e08ac59bb963f2 +4 -0
  46. gsuite_manager-0.3.0/.hypothesis/constants/69f49c039bab4712 +4 -0
  47. gsuite_manager-0.3.0/.hypothesis/constants/6c3c65e0402226f6 +4 -0
  48. gsuite_manager-0.3.0/.hypothesis/constants/74f64fb72c113dcb +4 -0
  49. gsuite_manager-0.3.0/.hypothesis/constants/78314297c8b7f421 +4 -0
  50. gsuite_manager-0.3.0/.hypothesis/constants/8003030ee846ab96 +4 -0
  51. gsuite_manager-0.3.0/.hypothesis/constants/8044b4f0b7390541 +4 -0
  52. gsuite_manager-0.3.0/.hypothesis/constants/8586aa5b90d9beac +4 -0
  53. gsuite_manager-0.3.0/.hypothesis/constants/9c2ced31e4a957d2 +4 -0
  54. gsuite_manager-0.3.0/.hypothesis/constants/9e2d420cdad15313 +4 -0
  55. gsuite_manager-0.3.0/.hypothesis/constants/9e7d3603f2a74075 +4 -0
  56. gsuite_manager-0.3.0/.hypothesis/constants/a2d160ea3cf51b50 +4 -0
  57. gsuite_manager-0.3.0/.hypothesis/constants/b6c4c372c8e67803 +4 -0
  58. gsuite_manager-0.3.0/.hypothesis/constants/b714a2788e5197c3 +4 -0
  59. gsuite_manager-0.3.0/.hypothesis/constants/b9a3943715e4fc1d +4 -0
  60. gsuite_manager-0.3.0/.hypothesis/constants/bea65b1a3227186f +4 -0
  61. gsuite_manager-0.3.0/.hypothesis/constants/c4752d9549d5e3f1 +4 -0
  62. gsuite_manager-0.3.0/.hypothesis/constants/cb4158fd3143b538 +4 -0
  63. gsuite_manager-0.3.0/.hypothesis/constants/cc2ccda28358debf +4 -0
  64. gsuite_manager-0.3.0/.hypothesis/constants/ce4bd9d0de3cdd21 +4 -0
  65. gsuite_manager-0.3.0/.hypothesis/constants/da39a3ee5e6b4b0d +4 -0
  66. gsuite_manager-0.3.0/.hypothesis/constants/e1ff7f5840c7b665 +4 -0
  67. gsuite_manager-0.3.0/.hypothesis/constants/eb054d45d654606e +4 -0
  68. gsuite_manager-0.3.0/.hypothesis/constants/f2bec7ffccba40ef +4 -0
  69. gsuite_manager-0.3.0/.hypothesis/unicode_data/15.0.0/charmap.json.gz +0 -0
  70. gsuite_manager-0.3.0/.hypothesis/unicode_data/15.0.0/codec-utf-8.json.gz +0 -0
  71. gsuite_manager-0.3.0/.pre-commit-config.yaml +26 -0
  72. gsuite_manager-0.3.0/AGENTS.md +52 -0
  73. gsuite_manager-0.3.0/CHANGELOG.md +75 -0
  74. gsuite_manager-0.3.0/CODE_OF_CONDUCT.md +54 -0
  75. gsuite_manager-0.3.0/CONTRIBUTING.md +109 -0
  76. gsuite_manager-0.3.0/LICENSE +21 -0
  77. gsuite_manager-0.3.0/Makefile +48 -0
  78. gsuite_manager-0.3.0/PKG-INFO +260 -0
  79. gsuite_manager-0.3.0/README.md +208 -0
  80. gsuite_manager-0.3.0/SECURITY.md +36 -0
  81. gsuite_manager-0.3.0/docs/assets/logo-dark.svg +13 -0
  82. gsuite_manager-0.3.0/docs/assets/logo.svg +13 -0
  83. gsuite_manager-0.3.0/docs/assets/social-preview.png +0 -0
  84. gsuite_manager-0.3.0/docs/assets/terminal.svg +59 -0
  85. gsuite_manager-0.3.0/docs/index.md +30 -0
  86. gsuite_manager-0.3.0/docs/production-runbook.md +159 -0
  87. gsuite_manager-0.3.0/docs/publishing.md +32 -0
  88. gsuite_manager-0.3.0/docs/reference/cli.md +7 -0
  89. gsuite_manager-0.3.0/docs/reference/clients.md +15 -0
  90. gsuite_manager-0.3.0/docs/reference/core.md +29 -0
  91. gsuite_manager-0.3.0/docs/reference/models.md +15 -0
  92. gsuite_manager-0.3.0/docs/reference/state.md +8 -0
  93. gsuite_manager-0.3.0/docs/setup.md +179 -0
  94. gsuite_manager-0.3.0/docs/troubleshooting.md +78 -0
  95. gsuite_manager-0.3.0/docs/usage.md +167 -0
  96. gsuite_manager-0.3.0/llms.txt +20 -0
  97. gsuite_manager-0.3.0/mkdocs.yml +75 -0
  98. gsuite_manager-0.3.0/pyproject.toml +126 -0
  99. gsuite_manager-0.3.0/scripts/smoke_test.sh +68 -0
  100. gsuite_manager-0.3.0/src/gsm/__init__.py +8 -0
  101. gsuite_manager-0.3.0/src/gsm/__main__.py +11 -0
  102. gsuite_manager-0.3.0/src/gsm/cli/__init__.py +77 -0
  103. gsuite_manager-0.3.0/src/gsm/cli/_shared.py +236 -0
  104. gsuite_manager-0.3.0/src/gsm/cli/commands/__init__.py +0 -0
  105. gsuite_manager-0.3.0/src/gsm/cli/commands/audit.py +149 -0
  106. gsuite_manager-0.3.0/src/gsm/cli/commands/dns.py +132 -0
  107. gsuite_manager-0.3.0/src/gsm/cli/commands/doctor.py +145 -0
  108. gsuite_manager-0.3.0/src/gsm/cli/commands/domains.py +508 -0
  109. gsuite_manager-0.3.0/src/gsm/cli/commands/expiry.py +115 -0
  110. gsuite_manager-0.3.0/src/gsm/cli/commands/go.py +144 -0
  111. gsuite_manager-0.3.0/src/gsm/cli/commands/groups.py +155 -0
  112. gsuite_manager-0.3.0/src/gsm/cli/commands/health.py +112 -0
  113. gsuite_manager-0.3.0/src/gsm/cli/commands/init.py +326 -0
  114. gsuite_manager-0.3.0/src/gsm/cli/commands/ledger.py +60 -0
  115. gsuite_manager-0.3.0/src/gsm/cli/commands/menu.py +435 -0
  116. gsuite_manager-0.3.0/src/gsm/cli/commands/users/__init__.py +39 -0
  117. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_aliases.py +67 -0
  118. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_app.py +11 -0
  119. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_audit.py +95 -0
  120. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_crud.py +343 -0
  121. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_gen.py +211 -0
  122. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_helpers.py +65 -0
  123. gsuite_manager-0.3.0/src/gsm/cli/commands/users/_suspend.py +83 -0
  124. gsuite_manager-0.3.0/src/gsm/clients/__init__.py +0 -0
  125. gsuite_manager-0.3.0/src/gsm/clients/_decorators.py +64 -0
  126. gsuite_manager-0.3.0/src/gsm/clients/_google_errors.py +54 -0
  127. gsuite_manager-0.3.0/src/gsm/clients/cloudflare.py +268 -0
  128. gsuite_manager-0.3.0/src/gsm/clients/dns_check.py +113 -0
  129. gsuite_manager-0.3.0/src/gsm/clients/google_admin.py +305 -0
  130. gsuite_manager-0.3.0/src/gsm/clients/google_verify.py +80 -0
  131. gsuite_manager-0.3.0/src/gsm/clients/mx_check.py +377 -0
  132. gsuite_manager-0.3.0/src/gsm/clients/username_generator.py +299 -0
  133. gsuite_manager-0.3.0/src/gsm/core/__init__.py +0 -0
  134. gsuite_manager-0.3.0/src/gsm/core/auth.py +114 -0
  135. gsuite_manager-0.3.0/src/gsm/core/config.py +94 -0
  136. gsuite_manager-0.3.0/src/gsm/core/errors.py +107 -0
  137. gsuite_manager-0.3.0/src/gsm/core/logging.py +83 -0
  138. gsuite_manager-0.3.0/src/gsm/models/__init__.py +0 -0
  139. gsuite_manager-0.3.0/src/gsm/models/constants.py +21 -0
  140. gsuite_manager-0.3.0/src/gsm/models/domain.py +33 -0
  141. gsuite_manager-0.3.0/src/gsm/models/results.py +38 -0
  142. gsuite_manager-0.3.0/src/gsm/models/user.py +39 -0
  143. gsuite_manager-0.3.0/src/gsm/state/__init__.py +0 -0
  144. gsuite_manager-0.3.0/src/gsm/state/ledger.py +199 -0
  145. gsuite_manager-0.3.0/src/gsm/workflows/__init__.py +0 -0
  146. gsuite_manager-0.3.0/src/gsm/workflows/domain_import.py +147 -0
  147. gsuite_manager-0.3.0/src/gsm/workflows/domain_onboarding.py +289 -0
  148. gsuite_manager-0.3.0/src/gsm/workflows/user_bulk_create.py +169 -0
  149. gsuite_manager-0.3.0/tests/__init__.py +0 -0
  150. gsuite_manager-0.3.0/tests/conftest.py +71 -0
  151. gsuite_manager-0.3.0/tests/fixtures/sample_domains.txt +152 -0
  152. gsuite_manager-0.3.0/tests/test_audit.py +206 -0
  153. gsuite_manager-0.3.0/tests/test_auth.py +181 -0
  154. gsuite_manager-0.3.0/tests/test_cli.py +628 -0
  155. gsuite_manager-0.3.0/tests/test_cli_commands.py +711 -0
  156. gsuite_manager-0.3.0/tests/test_cli_integration.py +385 -0
  157. gsuite_manager-0.3.0/tests/test_cli_interactive.py +304 -0
  158. gsuite_manager-0.3.0/tests/test_cloudflare.py +271 -0
  159. gsuite_manager-0.3.0/tests/test_config.py +159 -0
  160. gsuite_manager-0.3.0/tests/test_coverage_completion.py +621 -0
  161. gsuite_manager-0.3.0/tests/test_dns_check.py +154 -0
  162. gsuite_manager-0.3.0/tests/test_domain_import.py +254 -0
  163. gsuite_manager-0.3.0/tests/test_errors.py +76 -0
  164. gsuite_manager-0.3.0/tests/test_google_clients.py +619 -0
  165. gsuite_manager-0.3.0/tests/test_ledger.py +196 -0
  166. gsuite_manager-0.3.0/tests/test_logging.py +110 -0
  167. gsuite_manager-0.3.0/tests/test_mx_check.py +294 -0
  168. gsuite_manager-0.3.0/tests/test_property.py +202 -0
  169. gsuite_manager-0.3.0/tests/test_username_generator.py +264 -0
  170. gsuite_manager-0.3.0/tests/test_workflow_domain.py +345 -0
  171. 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,15 @@
1
+ # Default owner for everything
2
+ * @nopperabbo
3
+
4
+ # Source code
5
+ /src/ @nopperabbo
6
+
7
+ # Tests
8
+ /tests/ @nopperabbo
9
+
10
+ # CI/CD
11
+ /.github/ @nopperabbo
12
+
13
+ # Docs
14
+ /docs/ @nopperabbo
15
+ *.md @nopperabbo
@@ -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 }}