Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b179625
refactor: create isolated PHP XLSX domain generation toolkit
vitormattos Oct 8, 2026
34500f8
feat: add official-source verifier and PHP domain CLI
vitormattos Oct 8, 2026
3b5d71f
ci: replace Python generator job and monitor official sources
vitormattos Oct 8, 2026
fd28846
test: cover deterministic XLSX normalization and source integrity in …
vitormattos Oct 8, 2026
c2aa5af
fix: satisfy isolated tool tests, code style and REUSE metadata
vitormattos Oct 8, 2026
4f44458
build: lock isolated PhpSpreadsheet and PHPUnit dependencies
vitormattos Oct 8, 2026
173ea57
feat: detect newly published annex versions in official index pages
vitormattos Oct 8, 2026
bc3a91b
style: format government-index monitoring test
vitormattos Oct 8, 2026
425597e
ci: verify PHP generator against actual public production annexes
vitormattos Oct 8, 2026
a7519e9
chore: baseline authoritative A/B source hashes and inspect TSV diffe…
vitormattos Oct 8, 2026
071218f
test: identify official Anexo C description columns
vitormattos Oct 8, 2026
433691f
fix: preserve exact official Anexo C indicator columns D G H
vitormattos Oct 8, 2026
d0823af
test: align synthetic merged-characteristic fixture with real Anexo C
vitormattos Oct 8, 2026
7d48ef5
feat: inspect NT009 XLSX metadata and versioned indicator changes in PHP
vitormattos Oct 8, 2026
208a96b
test: verify NT009 workbook hashes and report source diffs with PHPUnit
vitormattos Oct 8, 2026
40b0bd4
feat: freeze all 40 verified official NT009 operation indicators
vitormattos Oct 8, 2026
db4d679
test: guard all NT009 indicators with offline and official XLSX compa…
vitormattos Oct 8, 2026
54cabab
fix: match official indicator worksheet names case-insensitively
vitormattos Oct 8, 2026
d5b2f74
test: retain synthetic merge ranges while exercising sheet-name norma…
vitormattos Oct 8, 2026
b21435d
Merge pull request #99 from LibreCodeCoop/feat/nt009-php-source-evidence
vitormattos Oct 8, 2026
a8e9939
refactor: centralize PHP CI compatibility policy in root Composer man…
vitormattos Oct 8, 2026
b953364
ci: replace repeated PHP versions with Composer-driven setup and test…
vitormattos Oct 8, 2026
dd0573d
refactor: extract offline-testable official annex download and snapsh…
vitormattos Oct 8, 2026
b6e17b6
ci: replace inline PHP workflows with testable CLI commands
vitormattos Oct 8, 2026
61d8c14
refactor: remove duplicated PHP requirement from isolated Composer to…
vitormattos Oct 8, 2026
75a08b2
build: lock isolated PHP tools without a duplicate PHP version constr…
vitormattos Oct 8, 2026
2603548
style: preserve existing Composer lockfile formatting
vitormattos Oct 8, 2026
da6cd5d
test: verify Composer manifests and reject unsafe annex source requests
vitormattos Oct 8, 2026
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
43 changes: 43 additions & 0 deletions .github/actions/setup-project-php/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later

name: Set up project PHP
description: Use the PHP compatibility contract in the root composer.json
inputs:
php-version:
description: Explicit CI matrix version, or empty for the Composer minimum
required: false
default: ""
extensions:
description: Extensions needed by the invoking job
required: false
default: "openssl, dom, soap"
coverage:
description: Coverage driver
required: false
default: "none"
ini-file:
description: PHP INI preset
required: false
default: ""
ini-values:
description: Additional INI values
required: false
default: ""
runs:
using: composite
steps:
- name: Validate root Composer PHP policy
id: php-policy
shell: bash
run: |
php tools/bin/ci-php.php validate
echo "minimum=$(php tools/bin/ci-php.php minimum)" >> "$GITHUB_OUTPUT"
- name: Install PHP
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
with:
php-version: ${{ inputs.php-version || steps.php-policy.outputs.minimum }}
extensions: ${{ inputs.extensions }}
coverage: ${{ inputs.coverage }}
ini-file: ${{ inputs.ini-file }}
ini-values: ${{ inputs.ini-values }}
23 changes: 19 additions & 4 deletions .github/workflows/domain-tables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ name: Domain Table Generator
on:
pull_request:
paths:
- "tools/generate_domain_tables.py"
- "tools/tests/test_generate_domain_tables.py"
- "tools/**"
- "vendor-bin/domains/**"
- "resources/domains/**"
- "composer.json"
- ".github/workflows/domain-tables.yml"
- ".github/actions/setup-project-php/**"
workflow_dispatch:

permissions:
contents: read
Expand All @@ -21,5 +24,17 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Test deterministic XLSX normalization
run: python3 -m unittest tools/tests/test_generate_domain_tables.py
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
extensions: dom, mbstring, zip, gd, xml, xmlreader, xmlwriter, simplexml, fileinfo
- name: Install isolated domain tooling
run: composer --working-dir=vendor-bin/domains install --prefer-dist --no-progress --no-interaction
- name: Validate root and isolated Composer manifests
run: |
composer validate --strict
composer --working-dir=vendor-bin/domains validate --strict
- name: Run offline deterministic PHPUnit cases
run: composer --working-dir=vendor-bin/domains run test
- name: Lint PHP domain tools
run: find tools -type f -name '*.php' -print0 | xargs -0 -n 1 php -l
6 changes: 2 additions & 4 deletions .github/workflows/lint-php-cs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ jobs:
with:
persist-credentials: false

- name: Set up PHP 8.2
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
php-version: "8.2"
extensions: openssl, dom, soap
coverage: none
ini-file: development
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/minimum-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ jobs:
with:
persist-credentials: false

- name: Set up PHP 8.2
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
php-version: "8.2"
extensions: openssl, dom, soap
coverage: none
ini-file: development
ini-values: disable_functions=
env:
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/nt009-evidence.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later

name: NT009 Source Evidence

on:
pull_request:
paths:
- "tools/**"
- "composer.json"
- "vendor-bin/domains/**"
- "resources/domains/**"
- ".github/workflows/nt009-evidence.yml"
- ".github/actions/setup-project-php/**"
workflow_dispatch:

permissions:
contents: read

jobs:
optional-official-evidence:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
extensions: dom, mbstring, zip, gd, xml, xmlreader, xmlwriter, simplexml, fileinfo
- name: Install isolated domain tooling
run: composer --working-dir=vendor-bin/domains install --prefer-dist --no-progress --no-interaction
- name: Verify original XLSX hashes and compare official NT009 data
run: |
php tools/bin/domains.php audit \
--download-dir="${{ runner.temp }}/nt009" \
--report="${{ runner.temp }}/nt009-comparison.json"
- name: Verify versioned Annex VII against all published XLSX rows
run: php tools/bin/domains.php verify-indicators --annex-vii="${{ runner.temp }}/nt009/annex-vii-nt009.xlsx"
- name: Retain full evidence for manual review
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: nt009-official-source-evidence
path: |
${{ runner.temp }}/nt009-comparison.json
${{ runner.temp }}/nt009/*.xlsx
if-no-files-found: warn
retention-days: 30
49 changes: 49 additions & 0 deletions .github/workflows/official-snapshot-reproduction.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later

name: Official Snapshot Reproduction

on:
pull_request:
paths:
- "tools/**"
- "composer.json"
- "vendor-bin/domains/**"
- "resources/domains/**"
- ".github/workflows/official-snapshot-reproduction.yml"
- ".github/actions/setup-project-php/**"
workflow_dispatch:

permissions:
contents: read

jobs:
advisory-production-snapshot-reproduction:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
extensions: dom, mbstring, zip, gd, xml, xmlreader, xmlwriter, simplexml, fileinfo
- name: Install isolated domain tooling
run: composer --working-dir=vendor-bin/domains install --prefer-dist --no-progress --no-interaction
- name: Download checksum-verified official production annexes
run: php tools/bin/domains.php download --ids=annex-a,annex-b,annex-c --output="${{ runner.temp }}/official"
- name: Compare regenerated output byte-for-byte with versioned snapshots
run: |
php tools/bin/domains.php check \
--annex-a="${{ runner.temp }}/official/annex-a.xlsx" \
--annex-b="${{ runner.temp }}/official/annex-b.xlsx" \
--annex-c="${{ runner.temp }}/official/annex-c.xlsx"
- name: Preserve source workbooks for manual review
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: official-production-domain-sources
path: ${{ runner.temp }}/official/*.xlsx
if-no-files-found: warn
retention-days: 14
35 changes: 27 additions & 8 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,44 @@ concurrency:
cancel-in-progress: true

jobs:
php-policy:
name: PHP versions from root Composer
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.policy.outputs.matrix }}
primary: ${{ steps.policy.outputs.primary }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Read CI PHP matrix and primary from composer.json
id: policy
run: |
php tools/bin/ci-php.php validate
echo "matrix=$(php tools/bin/ci-php.php matrix)" >> "$GITHUB_OUTPUT"
echo "primary=$(php tools/bin/ci-php.php primary)" >> "$GITHUB_OUTPUT"

compatibility:
name: PHP ${{ matrix.php-version }}
runs-on: ubuntu-latest
needs: php-policy

strategy:
matrix:
php-version: ["8.2", "8.3", "8.4"]
php-version: ${{ fromJSON(needs.php-policy.outputs.matrix) }}

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
- name: Set up PHP from Composer matrix
uses: ./.github/actions/setup-project-php
with:
php-version: ${{ matrix.php-version }}
extensions: openssl, dom, soap
coverage: none
ini-file: development
ini-values: disable_functions=
env:
Expand All @@ -48,7 +66,7 @@ jobs:
run: composer run test:unit

- name: Run integration tests when certificate secrets are present
if: ${{ matrix.php-version == '8.3' }}
if: ${{ matrix.php-version == needs.php-policy.outputs.primary }}
env:
NFSE_CLIENT_CERT_B64: ${{ secrets.NFSE_CLIENT_CERT_B64 }}
NFSE_CLIENT_KEY_B64: ${{ secrets.NFSE_CLIENT_KEY_B64 }}
Expand All @@ -64,17 +82,18 @@ jobs:
coverage:
name: Coverage
runs-on: ubuntu-latest
needs: php-policy

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up PHP 8.3
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
- name: Set up PHP from Composer primary
uses: ./.github/actions/setup-project-php
with:
php-version: "8.3"
php-version: ${{ needs.php-policy.outputs.primary }}
extensions: openssl, dom, soap
coverage: xdebug
ini-file: development
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/psalm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ jobs:
with:
persist-credentials: false

- name: Set up PHP 8.2
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
php-version: "8.2"
extensions: openssl, dom, soap
coverage: none
ini-file: development
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/source-watch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later

name: Official NFS-e Source Watch

on:
schedule:
- cron: "17 9 * * 1-5"
workflow_dispatch:

permissions:
contents: read

jobs:
check-published-files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up PHP from Composer
uses: ./.github/actions/setup-project-php
with:
extensions: dom, mbstring, zip, gd, xml, xmlreader, xmlwriter, simplexml, fileinfo
- name: Install isolated domain tooling
run: composer --working-dir=vendor-bin/domains install --prefer-dist --no-progress --no-interaction
- name: Compare official source checksums
run: php tools/bin/domains.php watch --report="${{ runner.temp }}/nfse-sources-report.json"
- name: Retain diff evidence without modifying the repository
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: official-nfse-source-check
path: ${{ runner.temp }}/nfse-sources-report.json
if-no-files-found: warn
retention-days: 30
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/.env
/.env.local
/.secrets/
/vendor-bin/domains/vendor/
1 change: 1 addition & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
->in([
__DIR__ . '/src',
__DIR__ . '/tests',
__DIR__ . '/tools',
])
->name('*.php')
->notPath('fixtures');
Expand Down
5 changes: 4 additions & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ default-copyright = "2026 LibreCode coop and contributors"
[[annotations]]
path = [
".gitignore",
"composer.json"
"composer.json",
"vendor-bin/domains/composer.json",
"vendor-bin/domains/composer.lock",
"resources/domains/sources.json"
]
precedence = "aggregate"
SPDX-FileCopyrightText = "2026 LibreCode coop and contributors"
Expand Down
Loading
Loading