autopkg-wrapper 2026.2.6__tar.gz → 2026.2.8__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 (49) hide show
  1. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.pre-commit-config.yaml +11 -3
  2. autopkg_wrapper-2026.2.8/.ruff.toml +14 -0
  3. autopkg_wrapper-2026.2.8/AGENTS.md +134 -0
  4. autopkg_wrapper-2026.2.8/PKG-INFO +242 -0
  5. autopkg_wrapper-2026.2.8/README.md +223 -0
  6. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/autopkg_wrapper.py +22 -15
  7. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/models/recipe.py +5 -1
  8. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/notifier/slack.py +8 -6
  9. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/git_functions.py +4 -3
  10. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/recipe_batching.py +22 -5
  11. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/recipe_ordering.py +13 -8
  12. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/report_processor.py +40 -43
  13. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/mise.toml +5 -1
  14. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/pyproject.toml +3 -1
  15. autopkg_wrapper-2026.2.8/scripts/generate_cli_docs.py +56 -0
  16. autopkg_wrapper-2026.2.8/tests/test_args_utils.py +74 -0
  17. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_autopkg_commands.py +63 -47
  18. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_git_functions.py +10 -15
  19. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_order_recipe_list.py +37 -35
  20. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_parse_recipe_list.py +46 -43
  21. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_report_processor.py +21 -28
  22. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_setup_logger.py +2 -7
  23. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_slack_notifier.py +6 -11
  24. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/uv.lock +95 -2
  25. autopkg_wrapper-2026.2.6/PKG-INFO +0 -107
  26. autopkg_wrapper-2026.2.6/README.md +0 -88
  27. autopkg_wrapper-2026.2.6/tests/test_args_utils.py +0 -79
  28. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/dependabot.yml +0 -0
  29. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/workflows/build-publish.yml +0 -0
  30. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/workflows/codeql.yml +0 -0
  31. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/workflows/dependency-review.yml +0 -0
  32. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.gitignore +0 -0
  33. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/CONTRIBUTING +0 -0
  34. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/LICENSE +0 -0
  35. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/.github/workflows/autopkg-wrapper-demo.yml +0 -0
  36. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/overrides/Google_Chrome.pkg.recipe.yaml +0 -0
  37. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/repo_list.txt +0 -0
  38. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/requirements.txt +0 -0
  39. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/__init__.py +0 -0
  40. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/notifier/__init__.py +0 -0
  41. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/__init__.py +0 -0
  42. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/args.py +0 -0
  43. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/logging.py +0 -0
  44. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/__init__.py +0 -0
  45. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/prefs.json +0 -0
  46. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/prefs.plist +0 -0
  47. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/recipe_list.json +0 -0
  48. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/recipe_list.txt +0 -0
  49. {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/recipe_list.yaml +0 -0
@@ -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,242 @@
1
+ Metadata-Version: 2.4
2
+ Name: autopkg-wrapper
3
+ Version: 2026.2.8
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] [--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
+ --debug Enable debug logging when running script
115
+ --disable-recipe-trust-check
116
+ If this option is used, recipe trust verification will
117
+ not be run prior to a recipe run. This does not set
118
+ FAIL_RECIPES_WITHOUT_TRUST_INFO to No. You will need
119
+ to set that outside of this application.
120
+ --disable-git-commands
121
+ If this option is used, git commands won't be run
122
+ --concurrency CONCURRENCY
123
+ Number of recipes to run in parallel (default: 1)
124
+ --github-token GITHUB_TOKEN
125
+ --branch-name BRANCH_NAME
126
+ Branch name to be used recipe overrides have failed
127
+ their trust verification and need to be updated. By
128
+ default, this will be in the format of
129
+ "fix/update_trust_information/YYYY-MM-DDTHH-MM-SS"
130
+ --create-pr If enabled, autopkg_wrapper will open a PR for updated
131
+ trust information
132
+ --create-issues Create a GitHub issue for recipes that fail during
133
+ processing
134
+ --overrides-repo-path OVERRIDES_REPO_PATH
135
+ The path on disk to the git repository containing the
136
+ autopkg overrides directory. If none is provided, we
137
+ will try to determine it for you.
138
+ --post-processors [POST_PROCESSORS ...]
139
+ One or more autopkg post processors to run after each
140
+ recipe execution
141
+ --autopkg-prefs AUTOPKG_PREFS
142
+ Path to the autopkg preferences you'd like to use
143
+ --process-reports Process autopkg report directories or zip and emit
144
+ markdown summaries
145
+ --reports-zip REPORTS_ZIP
146
+ Path to an autopkg_report-*.zip to extract and process
147
+ --reports-extract-dir REPORTS_EXTRACT_DIR
148
+ Directory to extract the zip into (default:
149
+ autopkg_reports_summary/reports)
150
+ --reports-dir REPORTS_DIR
151
+ Directory of reports to process (if no zip provided)
152
+ --reports-out-dir REPORTS_OUT_DIR
153
+ Directory to write markdown outputs (default:
154
+ autopkg_reports_summary/summary)
155
+ --reports-run-date REPORTS_RUN_DATE
156
+ Run date string to include in the summary
157
+ --reports-strict Exit non-zero if any errors are detected in processed
158
+ reports
159
+ ```
160
+
161
+ <!-- CLI-PARAMS-END -->
162
+
163
+ ## Examples
164
+
165
+ Run recipes (serial):
166
+
167
+ ```bash
168
+ autopkg_wrapper --recipes Foo.download Bar.download
169
+ ```
170
+
171
+ Run 3 recipes concurrently and process reports afterward:
172
+
173
+ ```bash
174
+ autopkg_wrapper \
175
+ --recipe-file /path/to/recipe_list.txt \
176
+ --concurrency 3 \
177
+ --disable-git-commands \
178
+ --process-reports \
179
+ --reports-out-dir /tmp/autopkg_reports_summary \
180
+ --reports-strict
181
+ ```
182
+
183
+ Process a reports zip explicitly (no recipe run):
184
+
185
+ ```bash
186
+ autopkg_wrapper \
187
+ --process-reports \
188
+ --reports-zip /path/to/autopkg_report-2026-02-02.zip \
189
+ --reports-extract-dir /tmp/autopkg_reports \
190
+ --reports-out-dir /tmp/autopkg_reports_summary
191
+ ```
192
+
193
+ ## Recipe Processing Flow
194
+
195
+ ```mermaid
196
+ flowchart TD
197
+ start([Start]) --> args[Parse CLI args]
198
+ args --> load[Load recipes list]
199
+ load --> order{Processing order provided?}
200
+ order -- Yes --> batches[Build recipe batches by type]
201
+ order -- No --> all[Single batch of all recipes]
202
+ batches --> log[Log each batch type and identifiers]
203
+ all --> log
204
+ log --> run[Run batch recipes concurrently within batch]
205
+ run --> next{More batches?}
206
+ next -- Yes --> log
207
+ next -- No --> git[Apply git updates serially]
208
+ git --> notify[Send notifications]
209
+ notify --> pr{Create PR?}
210
+ pr -- Yes --> createPR[Open trust update PR]
211
+ pr -- No --> issues{Create issues?}
212
+ createPR --> issues
213
+ issues -- Yes --> createIssue[Open failures issue]
214
+ issues -- No --> reports{Process reports?}
215
+ createIssue --> reports
216
+ reports -- Yes --> process[Process reports output]
217
+ reports -- No --> done([Done])
218
+ process --> done
219
+ ```
220
+
221
+ Related code:
222
+
223
+ - `autopkg_wrapper/autopkg_wrapper.py`
224
+ - `autopkg_wrapper/utils/recipe_batching.py`
225
+ - `autopkg_wrapper/utils/recipe_ordering.py`
226
+ - `autopkg_wrapper/utils/report_processor.py`
227
+ - `autopkg_wrapper/notifier/slack.py`
228
+
229
+ Notes:
230
+
231
+ - During recipe runs, per‑recipe plist reports are written to `/private/tmp/autopkg`.
232
+ - Log output references full recipe identifiers (for example, `Foo.upload.jamf`) and batch logs list recipe identifiers grouped by type.
233
+ - When `--process-reports` is supplied without `--reports-zip` or `--reports-dir`, the tool processes `/private/tmp/autopkg`.
234
+ - If `AUTOPKG_JSS_URL`, `AUTOPKG_CLIENT_ID`, and `AUTOPKG_CLIENT_SECRET` are set, uploaded package rows are enriched with Jamf package links.
235
+ - No extra CLI flag is required; enrichment runs automatically when all three env vars are present.
236
+
237
+ An example folder structure and GitHub Actions Workflow is available within the [`actions-demo`](actions-demo)
238
+
239
+ ## Credits
240
+
241
+ - [`autopkg_tools` from Facebook](https://github.com/facebook/IT-CPE/tree/main/legacy/autopkg_tools)
242
+ - [`autopkg_tools` from Facebook, modified by Gusto](https://github.com/Gusto/it-cpe-opensource/tree/main/autopkg)
@@ -0,0 +1,223 @@
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] [--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
+ --debug Enable debug logging when running script
96
+ --disable-recipe-trust-check
97
+ If this option is used, recipe trust verification will
98
+ not be run prior to a recipe run. This does not set
99
+ FAIL_RECIPES_WITHOUT_TRUST_INFO to No. You will need
100
+ to set that outside of this application.
101
+ --disable-git-commands
102
+ If this option is used, git commands won't be run
103
+ --concurrency CONCURRENCY
104
+ Number of recipes to run in parallel (default: 1)
105
+ --github-token GITHUB_TOKEN
106
+ --branch-name BRANCH_NAME
107
+ Branch name to be used recipe overrides have failed
108
+ their trust verification and need to be updated. By
109
+ default, this will be in the format of
110
+ "fix/update_trust_information/YYYY-MM-DDTHH-MM-SS"
111
+ --create-pr If enabled, autopkg_wrapper will open a PR for updated
112
+ trust information
113
+ --create-issues Create a GitHub issue for recipes that fail during
114
+ processing
115
+ --overrides-repo-path OVERRIDES_REPO_PATH
116
+ The path on disk to the git repository containing the
117
+ autopkg overrides directory. If none is provided, we
118
+ will try to determine it for you.
119
+ --post-processors [POST_PROCESSORS ...]
120
+ One or more autopkg post processors to run after each
121
+ recipe execution
122
+ --autopkg-prefs AUTOPKG_PREFS
123
+ Path to the autopkg preferences you'd like to use
124
+ --process-reports Process autopkg report directories or zip and emit
125
+ markdown summaries
126
+ --reports-zip REPORTS_ZIP
127
+ Path to an autopkg_report-*.zip to extract and process
128
+ --reports-extract-dir REPORTS_EXTRACT_DIR
129
+ Directory to extract the zip into (default:
130
+ autopkg_reports_summary/reports)
131
+ --reports-dir REPORTS_DIR
132
+ Directory of reports to process (if no zip provided)
133
+ --reports-out-dir REPORTS_OUT_DIR
134
+ Directory to write markdown outputs (default:
135
+ autopkg_reports_summary/summary)
136
+ --reports-run-date REPORTS_RUN_DATE
137
+ Run date string to include in the summary
138
+ --reports-strict Exit non-zero if any errors are detected in processed
139
+ reports
140
+ ```
141
+
142
+ <!-- CLI-PARAMS-END -->
143
+
144
+ ## Examples
145
+
146
+ Run recipes (serial):
147
+
148
+ ```bash
149
+ autopkg_wrapper --recipes Foo.download Bar.download
150
+ ```
151
+
152
+ Run 3 recipes concurrently and process reports afterward:
153
+
154
+ ```bash
155
+ autopkg_wrapper \
156
+ --recipe-file /path/to/recipe_list.txt \
157
+ --concurrency 3 \
158
+ --disable-git-commands \
159
+ --process-reports \
160
+ --reports-out-dir /tmp/autopkg_reports_summary \
161
+ --reports-strict
162
+ ```
163
+
164
+ Process a reports zip explicitly (no recipe run):
165
+
166
+ ```bash
167
+ autopkg_wrapper \
168
+ --process-reports \
169
+ --reports-zip /path/to/autopkg_report-2026-02-02.zip \
170
+ --reports-extract-dir /tmp/autopkg_reports \
171
+ --reports-out-dir /tmp/autopkg_reports_summary
172
+ ```
173
+
174
+ ## Recipe Processing Flow
175
+
176
+ ```mermaid
177
+ flowchart TD
178
+ start([Start]) --> args[Parse CLI args]
179
+ args --> load[Load recipes list]
180
+ load --> order{Processing order provided?}
181
+ order -- Yes --> batches[Build recipe batches by type]
182
+ order -- No --> all[Single batch of all recipes]
183
+ batches --> log[Log each batch type and identifiers]
184
+ all --> log
185
+ log --> run[Run batch recipes concurrently within batch]
186
+ run --> next{More batches?}
187
+ next -- Yes --> log
188
+ next -- No --> git[Apply git updates serially]
189
+ git --> notify[Send notifications]
190
+ notify --> pr{Create PR?}
191
+ pr -- Yes --> createPR[Open trust update PR]
192
+ pr -- No --> issues{Create issues?}
193
+ createPR --> issues
194
+ issues -- Yes --> createIssue[Open failures issue]
195
+ issues -- No --> reports{Process reports?}
196
+ createIssue --> reports
197
+ reports -- Yes --> process[Process reports output]
198
+ reports -- No --> done([Done])
199
+ process --> done
200
+ ```
201
+
202
+ Related code:
203
+
204
+ - `autopkg_wrapper/autopkg_wrapper.py`
205
+ - `autopkg_wrapper/utils/recipe_batching.py`
206
+ - `autopkg_wrapper/utils/recipe_ordering.py`
207
+ - `autopkg_wrapper/utils/report_processor.py`
208
+ - `autopkg_wrapper/notifier/slack.py`
209
+
210
+ Notes:
211
+
212
+ - During recipe runs, per‑recipe plist reports are written to `/private/tmp/autopkg`.
213
+ - Log output references full recipe identifiers (for example, `Foo.upload.jamf`) and batch logs list recipe identifiers grouped by type.
214
+ - When `--process-reports` is supplied without `--reports-zip` or `--reports-dir`, the tool processes `/private/tmp/autopkg`.
215
+ - If `AUTOPKG_JSS_URL`, `AUTOPKG_CLIENT_ID`, and `AUTOPKG_CLIENT_SECRET` are set, uploaded package rows are enriched with Jamf package links.
216
+ - No extra CLI flag is required; enrichment runs automatically when all three env vars are present.
217
+
218
+ An example folder structure and GitHub Actions Workflow is available within the [`actions-demo`](actions-demo)
219
+
220
+ ## Credits
221
+
222
+ - [`autopkg_tools` from Facebook](https://github.com/facebook/IT-CPE/tree/main/legacy/autopkg_tools)
223
+ - [`autopkg_tools` from Facebook, modified by Gusto](https://github.com/Gusto/it-cpe-opensource/tree/main/autopkg)