autopkg-wrapper 2026.2.6__tar.gz → 2026.2.9__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 (51) hide show
  1. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/.github/workflows/build-publish.yml +1 -1
  2. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/.github/workflows/codeql.yml +1 -1
  3. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/.github/workflows/dependency-review.yml +1 -1
  4. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/.pre-commit-config.yaml +11 -3
  5. autopkg_wrapper-2026.2.9/.ruff.toml +14 -0
  6. autopkg_wrapper-2026.2.9/AGENTS.md +134 -0
  7. autopkg_wrapper-2026.2.9/PKG-INFO +244 -0
  8. autopkg_wrapper-2026.2.9/README.md +225 -0
  9. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/autopkg_wrapper.py +133 -42
  10. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/models/recipe.py +41 -1
  11. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/notifier/slack.py +8 -6
  12. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/args.py +5 -0
  13. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/git_functions.py +4 -3
  14. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/recipe_batching.py +22 -5
  15. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/recipe_ordering.py +13 -8
  16. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/report_processor.py +232 -54
  17. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/mise.toml +5 -1
  18. autopkg_wrapper-2026.2.9/opencode.jsonc +10 -0
  19. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/pyproject.toml +3 -1
  20. autopkg_wrapper-2026.2.9/scripts/generate_cli_docs.py +56 -0
  21. autopkg_wrapper-2026.2.9/tests/test_args_utils.py +74 -0
  22. autopkg_wrapper-2026.2.9/tests/test_autopkg_commands.py +149 -0
  23. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/test_git_functions.py +10 -15
  24. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/test_order_recipe_list.py +37 -35
  25. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/test_parse_recipe_list.py +46 -43
  26. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/test_report_processor.py +73 -28
  27. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/test_setup_logger.py +2 -7
  28. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/test_slack_notifier.py +6 -11
  29. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/uv.lock +94 -2
  30. autopkg_wrapper-2026.2.6/PKG-INFO +0 -107
  31. autopkg_wrapper-2026.2.6/README.md +0 -88
  32. autopkg_wrapper-2026.2.6/tests/test_args_utils.py +0 -79
  33. autopkg_wrapper-2026.2.6/tests/test_autopkg_commands.py +0 -124
  34. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/.github/dependabot.yml +0 -0
  35. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/.gitignore +0 -0
  36. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/CONTRIBUTING +0 -0
  37. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/LICENSE +0 -0
  38. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/actions-demo/.github/workflows/autopkg-wrapper-demo.yml +0 -0
  39. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/actions-demo/overrides/Google_Chrome.pkg.recipe.yaml +0 -0
  40. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/actions-demo/repo_list.txt +0 -0
  41. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/actions-demo/requirements.txt +0 -0
  42. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/__init__.py +0 -0
  43. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/notifier/__init__.py +0 -0
  44. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/__init__.py +0 -0
  45. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/autopkg_wrapper/utils/logging.py +0 -0
  46. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/__init__.py +0 -0
  47. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/prefs.json +0 -0
  48. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/prefs.plist +0 -0
  49. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/recipe_list.json +0 -0
  50. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/recipe_list.txt +0 -0
  51. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.9}/tests/recipe_list.yaml +0 -0
@@ -103,7 +103,7 @@ jobs:
103
103
  id-token: write
104
104
 
105
105
  steps:
106
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
106
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
107
107
 
108
108
  - name: Setup mise
109
109
  uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
@@ -27,7 +27,7 @@ jobs:
27
27
 
28
28
  steps:
29
29
  - name: Checkout repository
30
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
30
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31
31
 
32
32
  - name: Initialize CodeQL
33
33
  uses: github/codeql-action/init@25a224b8085c21d4d61b7fc051468805fc3ac490 # codeql-bundle-v2.24.0
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - name: "Checkout Repository"
14
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
14
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
15
15
 
16
16
  - name: "Dependency Review"
17
17
  uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
@@ -14,20 +14,28 @@ repos:
14
14
  # hooks:
15
15
  # - id: gitleaks
16
16
  - repo: https://github.com/astral-sh/ruff-pre-commit
17
- rev: v0.12.10
17
+ rev: v0.14.14
18
18
  hooks:
19
19
  - id: ruff-check
20
20
  args: [--fix]
21
21
  - id: ruff-format
22
22
  - repo: https://github.com/astral-sh/uv-pre-commit
23
23
  # uv version.
24
- rev: 0.8.13
24
+ rev: 0.9.28
25
25
  hooks:
26
26
  - id: uv-lock
27
27
  - id: uv-sync
28
28
  args: ['--locked', '--all-packages']
29
+ - repo: local
30
+ hooks:
31
+ - id: generate-cli-docs
32
+ name: Generate CLI docs
33
+ entry: mise run docs-cli
34
+ language: system
35
+ pass_filenames: false
36
+ files: ^autopkg_wrapper/utils/args\.py$
29
37
  - repo: https://github.com/executablebooks/mdformat
30
- rev: 0.7.22
38
+ rev: 1.0.0
31
39
  hooks:
32
40
  - id: mdformat
33
41
  additional_dependencies:
@@ -0,0 +1,14 @@
1
+ line-length = 88
2
+ target-version = "py314"
3
+
4
+ [lint]
5
+ select = ["E", "F", "I", "B", "UP", "C4", "SIM"]
6
+ ignore = [
7
+ "E501",
8
+ ]
9
+
10
+ [format]
11
+ quote-style = "double"
12
+ indent-style = "space"
13
+ line-ending = "lf"
14
+ skip-magic-trailing-comma = false
@@ -0,0 +1,134 @@
1
+ # autopkg-wrapper Agent Notes
2
+
3
+ ## Overview
4
+
5
+ This repository provides `autopkg_wrapper`, a CLI for running AutoPkg recipes in CI/CD
6
+ with optional trust verification, batching/ordering, reporting, and notifications.
7
+
8
+ ## Environment
9
+
10
+ - Python is managed by `mise` (see `mise.toml`).
11
+ - Dependencies are managed by `uv`.
12
+ - Tests are run with `pytest`.
13
+ - Packaging uses `hatchling` via `uv build`.
14
+ - CLI entry point: `autopkg_wrapper/autopkg_wrapper.py`.
15
+
16
+ ## Build / Lint / Test Commands
17
+
18
+ Setup:
19
+
20
+ ```bash
21
+ mise run install
22
+ ```
23
+
24
+ Run tests:
25
+
26
+ ```bash
27
+ mise run test
28
+ ```
29
+
30
+ Run a single test file:
31
+
32
+ ```bash
33
+ uv run pytest tests/test_order_recipe_list.py -v
34
+ ```
35
+
36
+ Run a single test by name:
37
+
38
+ ```bash
39
+ uv run pytest -k "test_orders_by_type_then_alpha" -v
40
+ ```
41
+
42
+ Lint / format with Ruff:
43
+
44
+ ```bash
45
+ uv run ruff check .
46
+ uv run ruff format .
47
+ ```
48
+
49
+ Build package:
50
+
51
+ ```bash
52
+ mise run build
53
+ ```
54
+
55
+ Regenerate CLI docs:
56
+
57
+ ```bash
58
+ mise run docs-cli
59
+ ```
60
+
61
+ ## Code Style Guidelines
62
+
63
+ Formatting:
64
+
65
+ - Follow Ruff formatting defaults with project settings in `.ruff.toml`.
66
+ - Line length target is 88; `E501` is ignored but keep lines readable.
67
+ - Use double quotes; spaces for indentation; LF line endings.
68
+
69
+ Imports:
70
+
71
+ - Ruff enforces import sorting; keep stdlib, third-party, local separated.
72
+ - Prefer explicit imports over wildcard imports.
73
+ - Use local imports only when needed to avoid optional dependency issues.
74
+
75
+ Types and typing:
76
+
77
+ - Target Python 3.14 (`py314`).
78
+ - Use type hints for new functions, especially in utils and models.
79
+ - Prefer `list[str]`, `dict[str, T]`, and `Path` over legacy typing aliases.
80
+ - Use `Protocol` only when you need structural typing (see `recipe_batching.py`).
81
+
82
+ Naming:
83
+
84
+ - Modules and functions: `snake_case`.
85
+ - Classes: `PascalCase`.
86
+ - Constants: `UPPER_SNAKE_CASE`.
87
+ - Prefer descriptive variable names for recipes, batches, and paths.
88
+
89
+ Error handling:
90
+
91
+ - Use explicit exceptions when failing fast (see `parse_recipe_list`).
92
+ - Log errors with context; avoid swallowing exceptions unless necessary.
93
+ - When catching broad exceptions, add a comment or log explaining why.
94
+
95
+ Logging:
96
+
97
+ - Use `logging` from the stdlib.
98
+ - Keep log messages concise and user-actionable.
99
+ - Prefer structured or consistent message patterns for batch operations.
100
+
101
+ I/O and subprocess:
102
+
103
+ - Use `Path` for filesystem paths; avoid string path math.
104
+ - When calling subprocesses, capture output and log debug info.
105
+ - Keep command construction explicit for readability and auditability.
106
+
107
+ Recipes and ordering:
108
+
109
+ - Keep recipe identifiers as full filenames (e.g. `Foo.upload.jamf`).
110
+ - Ordering logic lives in `autopkg_wrapper/utils/recipe_ordering.py`.
111
+ - Batching logic lives in `autopkg_wrapper/utils/recipe_batching.py`.
112
+
113
+ Tests:
114
+
115
+ - Place tests in `tests/` with `test_*.py` naming.
116
+ - Use `pytest` fixtures or `SimpleNamespace` for lightweight args.
117
+ - Mock subprocess calls rather than invoking external tools.
118
+
119
+ Docs:
120
+
121
+ - User-facing behavior changes should be reflected in `README.md`.
122
+
123
+ ## Repository Notes
124
+
125
+ - No Cursor rules or Copilot instructions were found in this repo.
126
+ - If new rules are added under `.cursor/rules/`, `.cursorrules`,
127
+ or `.github/copilot-instructions.md`, include them here.
128
+
129
+ ## Key Paths
130
+
131
+ - CLI: `autopkg_wrapper/autopkg_wrapper.py`
132
+ - Recipe model: `autopkg_wrapper/models/recipe.py`
133
+ - Utils: `autopkg_wrapper/utils/`
134
+ - Tests: `tests/`
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: autopkg-wrapper
3
+ Version: 2026.2.9
4
+ Summary: A package used to execute some autopkg functions, primarily within the context of a GitHub Actions runner.
5
+ Project-URL: Repository, https://github.com/smithjw/autopkg-wrapper
6
+ Author-email: James Smith <james@smithjw.me>
7
+ License-Expression: BSD-3-Clause
8
+ License-File: LICENSE
9
+ Requires-Python: ~=3.14.0
10
+ Requires-Dist: chardet
11
+ Requires-Dist: idna
12
+ Requires-Dist: jamf-pro-sdk
13
+ Requires-Dist: pygithub
14
+ Requires-Dist: requests
15
+ Requires-Dist: ruamel-yaml
16
+ Requires-Dist: toml
17
+ Requires-Dist: urllib3
18
+ Description-Content-Type: text/markdown
19
+
20
+ # autopkg-wrapper
21
+
22
+ `autopkg_wrapper` is a small package that can be used to run [`autopkg`](https://github.com/autopkg/autopkg) within CI/CD environments such as GitHub Actions.
23
+
24
+ The easiest way to run it is by installing with pip.
25
+
26
+ ```shell
27
+ pip install autopkg-wrapper
28
+ ```
29
+
30
+ ## Development
31
+
32
+ This project uses `uv` for dependency management and `mise` tasks for common workflows.
33
+
34
+ ```bash
35
+ mise run install
36
+ mise run test
37
+ mise run build
38
+ ```
39
+
40
+ ## Command Line Parameters
41
+
42
+ <!-- CLI-PARAMS-START -->
43
+
44
+ ```shell
45
+ usage: autopkg_wrapper [-h] [--recipe-file RECIPE_FILE |
46
+ --recipes [RECIPES ...]]
47
+ [--recipe-processing-order [RECIPE_PROCESSING_ORDER ...]]
48
+ [--autopkg-bin AUTOPKG_BIN] [--dry-run] [--debug]
49
+ [--disable-recipe-trust-check] [--disable-git-commands]
50
+ [--concurrency CONCURRENCY]
51
+ [--github-token GITHUB_TOKEN]
52
+ [--branch-name BRANCH_NAME] [--create-pr]
53
+ [--create-issues]
54
+ [--overrides-repo-path OVERRIDES_REPO_PATH]
55
+ [--post-processors [POST_PROCESSORS ...]]
56
+ [--autopkg-prefs AUTOPKG_PREFS] [--process-reports]
57
+ [--reports-zip REPORTS_ZIP]
58
+ [--reports-extract-dir REPORTS_EXTRACT_DIR]
59
+ [--reports-dir REPORTS_DIR]
60
+ [--reports-out-dir REPORTS_OUT_DIR]
61
+ [--reports-run-date REPORTS_RUN_DATE]
62
+ [--reports-strict]
63
+
64
+ Run autopkg recipes
65
+
66
+ options:
67
+ -h, --help show this help message and exit
68
+ --recipe-file RECIPE_FILE
69
+ Provide the list of recipes to run via a JSON file for
70
+ easier management.
71
+ --recipes [RECIPES ...]
72
+ Recipes to run via CLI flag or environment variable.
73
+ If the '--recipes' flag is used, simply provide a
74
+ space-separated list on the command line: `autopkg-
75
+ wrapper --recipes recipe_one.download
76
+ recipe_two.download` Alternatively, you can provide a
77
+ space/comma-separated list in the 'AW_RECIPES'
78
+ environment variable: `export
79
+ AW_RECIPES="recipe_one.download recipe_two.download"`
80
+ `export AW_RECIPES="recipe_one.pkg,recipe_two.pkg"`
81
+ `autopkg-wrapper`
82
+ --recipe-processing-order [RECIPE_PROCESSING_ORDER ...]
83
+ This option comes in handy if you include additional
84
+ recipe type names in your overrides and wish them to
85
+ be processed in a specific order. We'll specifically
86
+ look for these recipe types after the first period (.)
87
+ in the recipe name. Order items can be either a full
88
+ type suffix (e.g. "upload.jamf") or a partial token
89
+ (e.g. "upload", "auto_update"). Partial tokens are
90
+ matched against the dot-separated segments after the
91
+ first '.' so recipes like "Foo.epz.auto_update.jamf"
92
+ will match "auto_update". This can also be provided
93
+ via the 'AW_RECIPE_PROCESSING_ORDER' environment
94
+ variable as a comma-separated list (e.g.
95
+ "upload,self_service,auto_update"). For example, if
96
+ you have the following recipes to be processed:
97
+ ExampleApp.auto_install.jamf ExampleApp.upload.jamf
98
+ ExampleApp.self_service.jamf And you want to ensure
99
+ that the .upload recipes are always processed first,
100
+ followed by .auto_install, and finally .self_service,
101
+ you would provide the following processing order:
102
+ `--recipe-processing-order upload.jamf
103
+ auto_install.jamf self_service.jamf` This would ensure
104
+ that all .upload recipes are processed before any
105
+ other recipe types. Within each recipe type, the
106
+ recipes will be ordered alphabetically. We assume that
107
+ no extensions are provided (but will strip them if
108
+ needed - extensions that are stripped include .recipe
109
+ or .recipe.yaml).
110
+ --autopkg-bin AUTOPKG_BIN
111
+ Path to the autopkg binary (default:
112
+ /usr/local/bin/autopkg). Can also be set via
113
+ AW_AUTOPKG_BIN.
114
+ --dry-run Show planned actions without executing external
115
+ commands
116
+ --debug Enable debug logging when running script
117
+ --disable-recipe-trust-check
118
+ If this option is used, recipe trust verification will
119
+ not be run prior to a recipe run. This does not set
120
+ FAIL_RECIPES_WITHOUT_TRUST_INFO to No. You will need
121
+ to set that outside of this application.
122
+ --disable-git-commands
123
+ If this option is used, git commands won't be run
124
+ --concurrency CONCURRENCY
125
+ Number of recipes to run in parallel (default: 1)
126
+ --github-token GITHUB_TOKEN
127
+ --branch-name BRANCH_NAME
128
+ Branch name to be used recipe overrides have failed
129
+ their trust verification and need to be updated. By
130
+ default, this will be in the format of
131
+ "fix/update_trust_information/YYYY-MM-DDTHH-MM-SS"
132
+ --create-pr If enabled, autopkg_wrapper will open a PR for updated
133
+ trust information
134
+ --create-issues Create a GitHub issue for recipes that fail during
135
+ processing
136
+ --overrides-repo-path OVERRIDES_REPO_PATH
137
+ The path on disk to the git repository containing the
138
+ autopkg overrides directory. If none is provided, we
139
+ will try to determine it for you.
140
+ --post-processors [POST_PROCESSORS ...]
141
+ One or more autopkg post processors to run after each
142
+ recipe execution
143
+ --autopkg-prefs AUTOPKG_PREFS
144
+ Path to the autopkg preferences you'd like to use
145
+ --process-reports Process autopkg report directories or zip and emit
146
+ markdown summaries
147
+ --reports-zip REPORTS_ZIP
148
+ Path to an autopkg_report-*.zip to extract and process
149
+ --reports-extract-dir REPORTS_EXTRACT_DIR
150
+ Directory to extract the zip into (default:
151
+ autopkg_reports_summary/reports)
152
+ --reports-dir REPORTS_DIR
153
+ Directory of reports to process (if no zip provided)
154
+ --reports-out-dir REPORTS_OUT_DIR
155
+ Directory to write markdown outputs (default:
156
+ autopkg_reports_summary/summary)
157
+ --reports-run-date REPORTS_RUN_DATE
158
+ Run date string to include in the summary
159
+ --reports-strict Exit non-zero if any errors are detected in processed
160
+ reports
161
+ ```
162
+
163
+ <!-- CLI-PARAMS-END -->
164
+
165
+ ## Examples
166
+
167
+ Run recipes (serial):
168
+
169
+ ```bash
170
+ autopkg_wrapper --recipes Foo.download Bar.download
171
+ ```
172
+
173
+ Run 3 recipes concurrently and process reports afterward:
174
+
175
+ ```bash
176
+ autopkg_wrapper \
177
+ --recipe-file /path/to/recipe_list.txt \
178
+ --concurrency 3 \
179
+ --disable-git-commands \
180
+ --process-reports \
181
+ --reports-out-dir /tmp/autopkg_reports_summary \
182
+ --reports-strict
183
+ ```
184
+
185
+ Process a reports zip explicitly (no recipe run):
186
+
187
+ ```bash
188
+ autopkg_wrapper \
189
+ --process-reports \
190
+ --reports-zip /path/to/autopkg_report-2026-02-02.zip \
191
+ --reports-extract-dir /tmp/autopkg_reports \
192
+ --reports-out-dir /tmp/autopkg_reports_summary
193
+ ```
194
+
195
+ ## Recipe Processing Flow
196
+
197
+ ```mermaid
198
+ flowchart TD
199
+ start([Start]) --> args[Parse CLI args]
200
+ args --> load[Load recipes list]
201
+ load --> order{Processing order provided?}
202
+ order -- Yes --> batches[Build recipe batches by type]
203
+ order -- No --> all[Single batch of all recipes]
204
+ batches --> log[Log each batch type and identifiers]
205
+ all --> log
206
+ log --> run[Run batch recipes concurrently within batch]
207
+ run --> next{More batches?}
208
+ next -- Yes --> log
209
+ next -- No --> git[Apply git updates serially]
210
+ git --> notify[Send notifications]
211
+ notify --> pr{Create PR?}
212
+ pr -- Yes --> createPR[Open trust update PR]
213
+ pr -- No --> issues{Create issues?}
214
+ createPR --> issues
215
+ issues -- Yes --> createIssue[Open failures issue]
216
+ issues -- No --> reports{Process reports?}
217
+ createIssue --> reports
218
+ reports -- Yes --> process[Process reports output]
219
+ reports -- No --> done([Done])
220
+ process --> done
221
+ ```
222
+
223
+ Related code:
224
+
225
+ - `autopkg_wrapper/autopkg_wrapper.py`
226
+ - `autopkg_wrapper/utils/recipe_batching.py`
227
+ - `autopkg_wrapper/utils/recipe_ordering.py`
228
+ - `autopkg_wrapper/utils/report_processor.py`
229
+ - `autopkg_wrapper/notifier/slack.py`
230
+
231
+ Notes:
232
+
233
+ - During recipe runs, per‑recipe plist reports are written to `/private/tmp/autopkg`.
234
+ - Log output references full recipe identifiers (for example, `Foo.upload.jamf`) and batch logs list recipe identifiers grouped by type.
235
+ - When `--process-reports` is supplied without `--reports-zip` or `--reports-dir`, the tool processes `/private/tmp/autopkg`.
236
+ - If `AUTOPKG_JSS_URL`, `AUTOPKG_CLIENT_ID`, and `AUTOPKG_CLIENT_SECRET` are set, uploaded package rows are enriched with Jamf package links.
237
+ - No extra CLI flag is required; enrichment runs automatically when all three env vars are present.
238
+
239
+ An example folder structure and GitHub Actions Workflow is available within the [`actions-demo`](actions-demo)
240
+
241
+ ## Credits
242
+
243
+ - [`autopkg_tools` from Facebook](https://github.com/facebook/IT-CPE/tree/main/legacy/autopkg_tools)
244
+ - [`autopkg_tools` from Facebook, modified by Gusto](https://github.com/Gusto/it-cpe-opensource/tree/main/autopkg)
@@ -0,0 +1,225 @@
1
+ # autopkg-wrapper
2
+
3
+ `autopkg_wrapper` is a small package that can be used to run [`autopkg`](https://github.com/autopkg/autopkg) within CI/CD environments such as GitHub Actions.
4
+
5
+ The easiest way to run it is by installing with pip.
6
+
7
+ ```shell
8
+ pip install autopkg-wrapper
9
+ ```
10
+
11
+ ## Development
12
+
13
+ This project uses `uv` for dependency management and `mise` tasks for common workflows.
14
+
15
+ ```bash
16
+ mise run install
17
+ mise run test
18
+ mise run build
19
+ ```
20
+
21
+ ## Command Line Parameters
22
+
23
+ <!-- CLI-PARAMS-START -->
24
+
25
+ ```shell
26
+ usage: autopkg_wrapper [-h] [--recipe-file RECIPE_FILE |
27
+ --recipes [RECIPES ...]]
28
+ [--recipe-processing-order [RECIPE_PROCESSING_ORDER ...]]
29
+ [--autopkg-bin AUTOPKG_BIN] [--dry-run] [--debug]
30
+ [--disable-recipe-trust-check] [--disable-git-commands]
31
+ [--concurrency CONCURRENCY]
32
+ [--github-token GITHUB_TOKEN]
33
+ [--branch-name BRANCH_NAME] [--create-pr]
34
+ [--create-issues]
35
+ [--overrides-repo-path OVERRIDES_REPO_PATH]
36
+ [--post-processors [POST_PROCESSORS ...]]
37
+ [--autopkg-prefs AUTOPKG_PREFS] [--process-reports]
38
+ [--reports-zip REPORTS_ZIP]
39
+ [--reports-extract-dir REPORTS_EXTRACT_DIR]
40
+ [--reports-dir REPORTS_DIR]
41
+ [--reports-out-dir REPORTS_OUT_DIR]
42
+ [--reports-run-date REPORTS_RUN_DATE]
43
+ [--reports-strict]
44
+
45
+ Run autopkg recipes
46
+
47
+ options:
48
+ -h, --help show this help message and exit
49
+ --recipe-file RECIPE_FILE
50
+ Provide the list of recipes to run via a JSON file for
51
+ easier management.
52
+ --recipes [RECIPES ...]
53
+ Recipes to run via CLI flag or environment variable.
54
+ If the '--recipes' flag is used, simply provide a
55
+ space-separated list on the command line: `autopkg-
56
+ wrapper --recipes recipe_one.download
57
+ recipe_two.download` Alternatively, you can provide a
58
+ space/comma-separated list in the 'AW_RECIPES'
59
+ environment variable: `export
60
+ AW_RECIPES="recipe_one.download recipe_two.download"`
61
+ `export AW_RECIPES="recipe_one.pkg,recipe_two.pkg"`
62
+ `autopkg-wrapper`
63
+ --recipe-processing-order [RECIPE_PROCESSING_ORDER ...]
64
+ This option comes in handy if you include additional
65
+ recipe type names in your overrides and wish them to
66
+ be processed in a specific order. We'll specifically
67
+ look for these recipe types after the first period (.)
68
+ in the recipe name. Order items can be either a full
69
+ type suffix (e.g. "upload.jamf") or a partial token
70
+ (e.g. "upload", "auto_update"). Partial tokens are
71
+ matched against the dot-separated segments after the
72
+ first '.' so recipes like "Foo.epz.auto_update.jamf"
73
+ will match "auto_update". This can also be provided
74
+ via the 'AW_RECIPE_PROCESSING_ORDER' environment
75
+ variable as a comma-separated list (e.g.
76
+ "upload,self_service,auto_update"). For example, if
77
+ you have the following recipes to be processed:
78
+ ExampleApp.auto_install.jamf ExampleApp.upload.jamf
79
+ ExampleApp.self_service.jamf And you want to ensure
80
+ that the .upload recipes are always processed first,
81
+ followed by .auto_install, and finally .self_service,
82
+ you would provide the following processing order:
83
+ `--recipe-processing-order upload.jamf
84
+ auto_install.jamf self_service.jamf` This would ensure
85
+ that all .upload recipes are processed before any
86
+ other recipe types. Within each recipe type, the
87
+ recipes will be ordered alphabetically. We assume that
88
+ no extensions are provided (but will strip them if
89
+ needed - extensions that are stripped include .recipe
90
+ or .recipe.yaml).
91
+ --autopkg-bin AUTOPKG_BIN
92
+ Path to the autopkg binary (default:
93
+ /usr/local/bin/autopkg). Can also be set via
94
+ AW_AUTOPKG_BIN.
95
+ --dry-run Show planned actions without executing external
96
+ commands
97
+ --debug Enable debug logging when running script
98
+ --disable-recipe-trust-check
99
+ If this option is used, recipe trust verification will
100
+ not be run prior to a recipe run. This does not set
101
+ FAIL_RECIPES_WITHOUT_TRUST_INFO to No. You will need
102
+ to set that outside of this application.
103
+ --disable-git-commands
104
+ If this option is used, git commands won't be run
105
+ --concurrency CONCURRENCY
106
+ Number of recipes to run in parallel (default: 1)
107
+ --github-token GITHUB_TOKEN
108
+ --branch-name BRANCH_NAME
109
+ Branch name to be used recipe overrides have failed
110
+ their trust verification and need to be updated. By
111
+ default, this will be in the format of
112
+ "fix/update_trust_information/YYYY-MM-DDTHH-MM-SS"
113
+ --create-pr If enabled, autopkg_wrapper will open a PR for updated
114
+ trust information
115
+ --create-issues Create a GitHub issue for recipes that fail during
116
+ processing
117
+ --overrides-repo-path OVERRIDES_REPO_PATH
118
+ The path on disk to the git repository containing the
119
+ autopkg overrides directory. If none is provided, we
120
+ will try to determine it for you.
121
+ --post-processors [POST_PROCESSORS ...]
122
+ One or more autopkg post processors to run after each
123
+ recipe execution
124
+ --autopkg-prefs AUTOPKG_PREFS
125
+ Path to the autopkg preferences you'd like to use
126
+ --process-reports Process autopkg report directories or zip and emit
127
+ markdown summaries
128
+ --reports-zip REPORTS_ZIP
129
+ Path to an autopkg_report-*.zip to extract and process
130
+ --reports-extract-dir REPORTS_EXTRACT_DIR
131
+ Directory to extract the zip into (default:
132
+ autopkg_reports_summary/reports)
133
+ --reports-dir REPORTS_DIR
134
+ Directory of reports to process (if no zip provided)
135
+ --reports-out-dir REPORTS_OUT_DIR
136
+ Directory to write markdown outputs (default:
137
+ autopkg_reports_summary/summary)
138
+ --reports-run-date REPORTS_RUN_DATE
139
+ Run date string to include in the summary
140
+ --reports-strict Exit non-zero if any errors are detected in processed
141
+ reports
142
+ ```
143
+
144
+ <!-- CLI-PARAMS-END -->
145
+
146
+ ## Examples
147
+
148
+ Run recipes (serial):
149
+
150
+ ```bash
151
+ autopkg_wrapper --recipes Foo.download Bar.download
152
+ ```
153
+
154
+ Run 3 recipes concurrently and process reports afterward:
155
+
156
+ ```bash
157
+ autopkg_wrapper \
158
+ --recipe-file /path/to/recipe_list.txt \
159
+ --concurrency 3 \
160
+ --disable-git-commands \
161
+ --process-reports \
162
+ --reports-out-dir /tmp/autopkg_reports_summary \
163
+ --reports-strict
164
+ ```
165
+
166
+ Process a reports zip explicitly (no recipe run):
167
+
168
+ ```bash
169
+ autopkg_wrapper \
170
+ --process-reports \
171
+ --reports-zip /path/to/autopkg_report-2026-02-02.zip \
172
+ --reports-extract-dir /tmp/autopkg_reports \
173
+ --reports-out-dir /tmp/autopkg_reports_summary
174
+ ```
175
+
176
+ ## Recipe Processing Flow
177
+
178
+ ```mermaid
179
+ flowchart TD
180
+ start([Start]) --> args[Parse CLI args]
181
+ args --> load[Load recipes list]
182
+ load --> order{Processing order provided?}
183
+ order -- Yes --> batches[Build recipe batches by type]
184
+ order -- No --> all[Single batch of all recipes]
185
+ batches --> log[Log each batch type and identifiers]
186
+ all --> log
187
+ log --> run[Run batch recipes concurrently within batch]
188
+ run --> next{More batches?}
189
+ next -- Yes --> log
190
+ next -- No --> git[Apply git updates serially]
191
+ git --> notify[Send notifications]
192
+ notify --> pr{Create PR?}
193
+ pr -- Yes --> createPR[Open trust update PR]
194
+ pr -- No --> issues{Create issues?}
195
+ createPR --> issues
196
+ issues -- Yes --> createIssue[Open failures issue]
197
+ issues -- No --> reports{Process reports?}
198
+ createIssue --> reports
199
+ reports -- Yes --> process[Process reports output]
200
+ reports -- No --> done([Done])
201
+ process --> done
202
+ ```
203
+
204
+ Related code:
205
+
206
+ - `autopkg_wrapper/autopkg_wrapper.py`
207
+ - `autopkg_wrapper/utils/recipe_batching.py`
208
+ - `autopkg_wrapper/utils/recipe_ordering.py`
209
+ - `autopkg_wrapper/utils/report_processor.py`
210
+ - `autopkg_wrapper/notifier/slack.py`
211
+
212
+ Notes:
213
+
214
+ - During recipe runs, per‑recipe plist reports are written to `/private/tmp/autopkg`.
215
+ - Log output references full recipe identifiers (for example, `Foo.upload.jamf`) and batch logs list recipe identifiers grouped by type.
216
+ - When `--process-reports` is supplied without `--reports-zip` or `--reports-dir`, the tool processes `/private/tmp/autopkg`.
217
+ - If `AUTOPKG_JSS_URL`, `AUTOPKG_CLIENT_ID`, and `AUTOPKG_CLIENT_SECRET` are set, uploaded package rows are enriched with Jamf package links.
218
+ - No extra CLI flag is required; enrichment runs automatically when all three env vars are present.
219
+
220
+ An example folder structure and GitHub Actions Workflow is available within the [`actions-demo`](actions-demo)
221
+
222
+ ## Credits
223
+
224
+ - [`autopkg_tools` from Facebook](https://github.com/facebook/IT-CPE/tree/main/legacy/autopkg_tools)
225
+ - [`autopkg_tools` from Facebook, modified by Gusto](https://github.com/Gusto/it-cpe-opensource/tree/main/autopkg)