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.
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.pre-commit-config.yaml +11 -3
- autopkg_wrapper-2026.2.8/.ruff.toml +14 -0
- autopkg_wrapper-2026.2.8/AGENTS.md +134 -0
- autopkg_wrapper-2026.2.8/PKG-INFO +242 -0
- autopkg_wrapper-2026.2.8/README.md +223 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/autopkg_wrapper.py +22 -15
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/models/recipe.py +5 -1
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/notifier/slack.py +8 -6
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/git_functions.py +4 -3
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/recipe_batching.py +22 -5
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/recipe_ordering.py +13 -8
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/report_processor.py +40 -43
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/mise.toml +5 -1
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/pyproject.toml +3 -1
- autopkg_wrapper-2026.2.8/scripts/generate_cli_docs.py +56 -0
- autopkg_wrapper-2026.2.8/tests/test_args_utils.py +74 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_autopkg_commands.py +63 -47
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_git_functions.py +10 -15
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_order_recipe_list.py +37 -35
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_parse_recipe_list.py +46 -43
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_report_processor.py +21 -28
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_setup_logger.py +2 -7
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/test_slack_notifier.py +6 -11
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/uv.lock +95 -2
- autopkg_wrapper-2026.2.6/PKG-INFO +0 -107
- autopkg_wrapper-2026.2.6/README.md +0 -88
- autopkg_wrapper-2026.2.6/tests/test_args_utils.py +0 -79
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/dependabot.yml +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/workflows/build-publish.yml +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/workflows/codeql.yml +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.github/workflows/dependency-review.yml +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/.gitignore +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/CONTRIBUTING +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/LICENSE +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/.github/workflows/autopkg-wrapper-demo.yml +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/overrides/Google_Chrome.pkg.recipe.yaml +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/repo_list.txt +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/actions-demo/requirements.txt +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/__init__.py +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/notifier/__init__.py +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/__init__.py +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/args.py +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/autopkg_wrapper/utils/logging.py +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/__init__.py +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/prefs.json +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/prefs.plist +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/recipe_list.json +0 -0
- {autopkg_wrapper-2026.2.6 → autopkg_wrapper-2026.2.8}/tests/recipe_list.txt +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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)
|