diff --git a/.github/workflows/tag-currency.yml b/.github/workflows/tag-currency.yml index c3173f1..be1ce8a 100644 --- a/.github/workflows/tag-currency.yml +++ b/.github/workflows/tag-currency.yml @@ -31,19 +31,13 @@ concurrency: jobs: tag-currency: name: tag currency - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Checkout - uses: actions/checkout@v7 - with: - # The whole history and every tag. The default shallow checkout has - # neither, and `git merge-base --is-ancestor` on a graph that stops at - # one commit answers "not an ancestor" for tags that are perfectly - # fine — the same false alarm that made the previous version of this - # check unusable. - fetch-depth: 0 - fetch-tags: true - - - name: Verify the tag consumers resolve is on main - run: bash scripts/verify-tag-currency.sh main origin + # The shared hygiene workflow runs laranail/package-tools' canonical check + # over the API, so neither a checkout nor fetch depth matters any more. + # Release tags are immutable: a tag behind main is a warning that a release + # is due, never a red run. scripts/verify-tag-currency.sh is deprecated and + # delegates to the same canonical script when run by hand. + uses: laranail/.github/.github/workflows/hygiene.yml@main + with: + run-action-pins: false + run-tag-currency: true + run-dist-integrity: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 4835bd5..20eeff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,19 @@ Entries below `Unreleased` are written by CI from the GitHub release body — se > part of `v0.1.0`. They are kept for provenance, not because those versions are installable. ## [Unreleased] +### Changed + +- The weekly tag-currency workflow now calls `laranail/.github`'s shared hygiene workflow, which + uses `laranail/package-tools`' canonical script. Release tags are immutable, so a tag behind `main` + is a warning that a release is due rather than a red run. + +### Deprecated + +- `scripts/verify-tag-currency.sh`. It prints a notice and delegates to the canonical script when + an installed `laranail/package-tools` already follows the immutable-tag model, and otherwise keeps + working, now advising the next patch instead of a moved tag. Earliest removal: the next minor + release. + ### Fixed - **`composer rector` failed with `Class "Rector\Transform\ValueObject\ArrayDimFetchToMethodCall" not found`.** diff --git a/scripts/verify-tag-currency.sh b/scripts/verify-tag-currency.sh index 3b12a97..3fe5526 100755 --- a/scripts/verify-tag-currency.sh +++ b/scripts/verify-tag-currency.sh @@ -59,6 +59,20 @@ # Only meaningful pre-1.0. From 1.0 the tag is immutable by design and this # exits without an opinion. +# DEPRECATED since 2026-11-02, earliest removal in this package's next minor release. +# The canonical check is laranail/package-tools' scripts/verify-tag-currency.sh, which CI runs +# through laranail/.github's shared hygiene workflow. It follows the immutable-tag model: a tag +# behind main is a release that is due (a warning), never a tag to move. This copy prints a notice +# and delegates to that script when an installed copy (vendor/) already follows that model and `gh` +# is available; otherwise it keeps working as before, so a caller that was not found does not break. +echo "::notice::scripts/verify-tag-currency.sh is deprecated; use laranail/package-tools' scripts/verify-tag-currency.sh (CI runs it through laranail/.github's hygiene workflow)." >&2 +canonical="$(cd "$(dirname "$0")/.." && pwd)/vendor/laranail/package-tools/scripts/verify-tag-currency.sh" +if [ -f "${canonical}" ] && grep -q 'title=Release due' "${canonical}" && command -v gh >/dev/null 2>&1; then + # This copy takes [branch] [remote]; the canonical one takes [branch]. + repo=$(git remote get-url "${2:-origin}" | sed -E 's#^(git@github\.com:|https://github\.com/)##; s#\.git$##') + exec bash "${canonical}" "${repo}" "${1:-main}" +fi + set -euo pipefail BRANCH="${1:-main}" @@ -191,7 +205,7 @@ else elif released; then fail "${current} is behind ${BRANCH}. It is a published release, so do not move it: cut ${current%.*}.$(( ${current##*.} + 1 ))." else - fail "${current} is behind ${BRANCH}. Move it (git tag -f ${current} ${BRANCH} && git push --force ${REMOTE} ${current}) or cut a new one." + fail "${current} is behind ${BRANCH}. Tags are immutable, so do not move it: cut ${current%.*}.$(( ${current##*.} + 1 ))." fi fi diff --git a/src/Builder/Concerns/HasFieldModifiers.php b/src/Builder/Concerns/HasFieldModifiers.php index 14bd115..eda1939 100644 --- a/src/Builder/Concerns/HasFieldModifiers.php +++ b/src/Builder/Concerns/HasFieldModifiers.php @@ -262,7 +262,7 @@ public function excludeUnless(Closure|bool|string $field, string|int|bool|Backed } // Laravel 11: evaluate eagerly (inverted excludeIf) - $shouldExclude = $field instanceof Closure ? ! $field() : ! $field; + $shouldExclude = $field instanceof Closure ? ! (bool) $field() : ! $field; return $shouldExclude ? $this->addRule('exclude') : $this; } diff --git a/src/FastCheck/Shared/LaravelEmptiness.php b/src/FastCheck/Shared/LaravelEmptiness.php index d6fb6e5..6b6b10b 100644 --- a/src/FastCheck/Shared/LaravelEmptiness.php +++ b/src/FastCheck/Shared/LaravelEmptiness.php @@ -40,7 +40,7 @@ public static function isEmpty(mixed $value): bool } if ($value instanceof File) { - return (string) $value->getPath() === ''; + return $value->getPath() === ''; } return false; diff --git a/src/PresenceConditionalReducer.php b/src/PresenceConditionalReducer.php index 4aaed90..0a1888b 100644 --- a/src/PresenceConditionalReducer.php +++ b/src/PresenceConditionalReducer.php @@ -176,7 +176,7 @@ private static function fieldPresent(array $itemData, ?string $field): bool } if ($value instanceof UploadedFile) { - return (string) $value->getPath() !== ''; + return $value->getPath() !== ''; } return true;