Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/DISCUSSION_TEMPLATE/ideas.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
title: "[Idea] "
labels: ["idea"]
body:
- type: markdown
attributes:
value: |
Ideas for new packing rules, outputs or integrations. An idea the maintainers take on
is moved to an issue and linked back here, so you can follow it.
- type: textarea
id: problem
attributes:
label: The problem behind the idea
description: What real shipment or load does today's library not handle?
validations:
required: true
- type: textarea
id: idea
attributes:
label: The idea
validations:
required: true
- type: input
id: package
attributes:
label: Package(s) you use
placeholder: "packvium/packvium"
validations:
required: false
30 changes: 30 additions & 0 deletions .github/DISCUSSION_TEMPLATE/q-a.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
title: "[Q&A] "
labels: ["question"]
body:
- type: markdown
attributes:
value: |
Ask anything about using the library. If you have found a wrong result or an error,
a bug report is the better place.
- type: input
id: package-version
attributes:
label: Package and version
placeholder: "packvium/packvium 1.8.0 (PHP)"
validations:
required: true
- type: textarea
id: question
attributes:
label: Your question
description: What you are trying to pack, and what you tried.
validations:
required: true
- type: textarea
id: request
attributes:
label: Request (optional)
description: The JSON request or code, if it helps.
render: json
validations:
required: false
33 changes: 33 additions & 0 deletions .github/DISCUSSION_TEMPLATE/show-and-tell.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
title: "[Show and tell] "
labels: ["show-and-tell"]
body:
- type: markdown
attributes:
value: |
Using the library in a shop, a warehouse tool or a load planner? Tell us how. Leave out
anything confidential about your business.
- type: textarea
id: what
attributes:
label: What you built
validations:
required: true
- type: input
id: package-version
attributes:
label: Package and version
placeholder: "packvium/packvium 1.8.0 (PHP)"
validations:
required: false
- type: textarea
id: lessons
attributes:
label: What worked, and what got in the way
validations:
required: false
- type: input
id: link
attributes:
label: Link (optional)
validations:
required: false
105 changes: 105 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Bug report
description: A result that is wrong, an error you did not expect, or a crash.
title: "[Bug]: "
labels: ["bug", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for reporting. A report we can run is a report we can fix, so the most useful
thing below is the smallest request that shows the problem.

**Security problems do not belong here.** Use **Report a vulnerability** under the
Security tab instead; it opens a private advisory.
- type: dropdown
id: package
attributes:
label: Package
description: Which package did you call?
options:
- "packvium (PyPI) — Packvium for Python"
- "packvium-native (PyPI) — Packvium native backend selector for Python"
- "packvium/packvium (Packagist) — Packvium for PHP"
- "packvium/native-bridge (Packagist) — Packvium native bridge for PHP"
- "@packvium/engine (npm) — Packvium for Node.js"
- "@packvium/browser (npm) — Packvium for browsers"
- "packvium (crates.io) — Packvium for Rust"
- "packvium-native-rust (PyPI) — Packvium native engines: Python wheels, Node addons and the C library"
- Not sure
default: 2
validations:
required: true
- type: input
id: version
attributes:
label: Package version
description: The exact version installed, for example 1.8.0.
placeholder: "1.8.0"
validations:
required: true
- type: input
id: runtime
attributes:
label: Runtime and operating system
description: Language runtime version and OS, for example "Python 3.12, Ubuntu 24.04" or "PHP 8.3, macOS 15".
validations:
required: true
- type: dropdown
id: profile
attributes:
label: Search profile
options:
- fast
- balanced
- quality
- exact_small
- Not set / default
- Not sure
validations:
required: false
- type: textarea
id: request
attributes:
label: Request that reproduces it
description: |
The JSON request, or the code that builds it, cut down as far as it still shows the
problem. Remove anything confidential; renamed item ids are fine.
render: json
validations:
required: true
- type: textarea
id: actual
attributes:
label: What happened
description: The result (or its relevant part), or the full error message and stack trace.
render: text
validations:
required: true
- type: textarea
id: expected
attributes:
label: What you expected
description: What the result should have been, and why. If another of the packages gives a different answer for the same request, say which.
validations:
required: true
- type: dropdown
id: stopped-by
attributes:
label: How was the search limited?
description: A search stopped by a time limit can differ between runs by design; one stopped by an effort budget cannot.
options:
- effort_budget
- time_limit_ms
- Both
- Neither / not sure
validations:
required: false
- type: checkboxes
id: checks
attributes:
label: Before submitting
options:
- label: I searched the existing issues and did not find this one.
required: true
- label: I read [docs/GUARANTEES.md](https://github.com/toxakara/packvium-php/blob/HEAD/docs/GUARANTEES.md) and this is not something it says the library does not guarantee.
required: false
11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Question or help with a request
url: https://github.com/toxakara/packvium-php/discussions/categories/q-a
about: Ask in Discussions → Q&A. Answers there help the next person too.
- name: Report a security vulnerability
url: https://github.com/toxakara/packvium-php/security/advisories/new
about: Report privately. Do not open a public issue for a security problem.
- name: Documentation
url: https://packvium.com/docs
about: Guides, the request contract and the constraint reference.
62 changes: 62 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Feature request
description: A packing rule, constraint, output or integration the library does not support yet.
title: "[Feature]: "
labels: ["enhancement", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Open-ended ideas are welcome in **Discussions → Ideas** first. Use this form when you can
describe a concrete problem the library does not solve today.
- type: dropdown
id: package
attributes:
label: Package you use
options:
- "packvium (PyPI) — Packvium for Python"
- "packvium-native (PyPI) — Packvium native backend selector for Python"
- "packvium/packvium (Packagist) — Packvium for PHP"
- "packvium/native-bridge (Packagist) — Packvium native bridge for PHP"
- "@packvium/engine (npm) — Packvium for Node.js"
- "@packvium/browser (npm) — Packvium for browsers"
- "packvium (crates.io) — Packvium for Rust"
- "packvium-native-rust (PyPI) — Packvium native engines: Python wheels, Node addons and the C library"
- More than one
default: 2
validations:
required: true
- type: input
id: version
attributes:
label: Package version
placeholder: "1.8.0"
validations:
required: true
- type: textarea
id: problem
attributes:
label: The problem
description: What are you packing, into what, and what rule or output is missing? A real (anonymised) example helps more than a general description.
validations:
required: true
- type: textarea
id: proposal
attributes:
label: What you would like
description: The behaviour or field you have in mind, if you have one.
validations:
required: false
- type: textarea
id: workaround
attributes:
label: What you do today
description: Any workaround you use, and what it costs you.
validations:
required: false
- type: markdown
attributes:
value: |
Every package implements one shared contract, so a new rule or result field lands in all
of them together, and a change to the request or result format waits for a release that
is allowed to change it. A request that is accepted may therefore take more than one
release to ship.
47 changes: 47 additions & 0 deletions .github/workflows/rc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: rc

# Packagist does not take an upload: it reads this repository's tags, and imports a
# pre-release tag (`v1.9.0-rc.1`) as an RC-stability version. Composer skips it under the
# default `minimum-stability: stable`, so a consumer opts in explicitly:
# composer require packvium/packvium:<version>@RC
# This workflow runs the same checks `release.yml` runs. A bad RC tag gets a red check,
# but that does not prevent Packagist from importing the tag. Check before pushing it.
# There is no GitHub Release: an RC is not a release.
# Nothing is needed from the owner: the repository is already linked on Packagist.

on:
push:
tags: ["v*-*"]

permissions:
contents: read

jobs:
verify-tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
with:
php-version: "8.3"
coverage: none

# composer.json deliberately carries no `version` field -- Composer derives it from
# the tag, and a hand-maintained copy only ever drifts. The changelog is the file
# that does state a version, so that is what the tag is checked against: a tag with
# no matching changelog entry is a release nobody wrote down.
- name: The tag must have a changelog entry
run: |
tagged="${GITHUB_REF_NAME#v}"
if ! grep -q "^## \[${tagged}\]" CHANGELOG.md; then
echo "CHANGELOG.md has no '## [${tagged}]' section for tag $GITHUB_REF_NAME" >&2
exit 1
fi

- run: composer validate --strict --no-check-lock
- name: Lint every shipped file
run: |
for file in $(find src tests examples -name '*.php') bin/packvium; do
php -l "$file" > /dev/null
done
- run: php tests/run.php
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ name: release
# https://packagist.org/packages/submit and enable the GitHub service hook it offers, so
# later tags are picked up without anyone pressing "Update".

# A pre-release tag (`v1.9.0-rc.1`) never reaches the production registries: the negated
# pattern must follow the positive one, and `rc.yml` takes those tags instead.
on:
push:
tags: ["v*"]
tags: ["v*", "!v*-*"]

permissions:
contents: read
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
/.phpunit.cache/
/.php-cs-fixer.cache
/composer.lock
/build/
/tools/php-compat/vendor/
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@ What changed in `packvium/packvium` on Packagist, release by release. The format
[Keep a Changelog](https://keepachangelog.com/1.1.0/) and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.8.0]

Results now say how far they can be from the best possible answer, `optimal` means a proof,
and a mistyped flag is refused instead of guessed.

### Added

- **`optimality.lower_bound` and the gap** under the `default` and `lowest_cost` objectives;
`Packvium\Validation\validate` checks them.
- **The `src-legacy/` generator** (`scripts/build_php74.py`, `tools/php-compat/`), which
rebuilds the shipped tree byte for byte from a tag.

### Changed

- **Attaining the bound, not search exhaustion, sets `optimal`** (`proven_optimal`).
- **An effort budget names a stop:** a run that ends on exactly its budget is `complete`, and
`time_limit_ms` is no longer split across starts. Check `termination.any_start_truncated`.
- **`ArrayCodec::pack` refuses a non-boolean `keep_upright`, `stackable`, `must_be_on_floor`
or `require_placement_coordinates`** as `wrong_type`; `"no"` packed as stackable. The
constructors are unchanged: without `strict_types`, PHP still converts the value.
`Packvium\Validation\validate` throws `MalformedResult` (`contract`) for such a request, and
reads `null` as the default.
- **Solves 2-15% faster**, the loading-order check about twice as fast, identical answers.
- **The JSON path avoids a redundant object check:** `ArrayCodec::pack` retains request
admission and model checks, and compiles fewer files. Direct measurements on the macOS
host removed about 0.5 ms of compilation/checking work on the unpackable request; the
additional end-to-end gain was within the A/A noise. This is wall time, not CPU time.
- **Placement under axle limits is about 2.5-3x faster**, unloading orders about 5% faster;
answers are identical.

### Fixed

- **`homogeneous_blocks` named alone packs under `fast` and `balanced`**, and a node-limit
stop is no longer reported as `time_limit`.
- **A bound past the declared ceiling no longer throws `BoundOverflowException`.**
- **`validate` reads `units: null` and `units.length: null` as millimetres**, as the engines do,
and refuses a `units` that is not an object, or an unknown `units.length`, as a `contract`
`MalformedResult` naming the field. `units.weight` is not a field and is ignored: put the unit
on each weight.

## [1.7.0]

The reference validator ships in the package, `quality` looks ahead in its block solver, and a
Expand Down
Loading
Loading