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
14 changes: 14 additions & 0 deletions references/schemas/nfse/1.01/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ GitHub stores file contents as content-addressed Git blobs. The blob IDs below p
| `tiposComplexos_v1.01.xsd` | `91f44b804ddcba93c65f7dea923ca4621c1dcd6a` |
| `tiposSimples_v1.01.xsd` | `6cf3dcb9c085e284a9b78b9a6a4c2688a95df5e9` |
| `xmldsig-core-schema.xsd` | `8a9c9139d0cb2c3497ce67942ba7d1e8528241d0` |
| `pedRegEvento_v1.01.xsd` | `d8d3db9afdb2b79d6c32dd6d2ed727dcc6e22a6a` |
| `tiposEventos_v1.01.xsd` | `1a568683f6cb5e1ca65b5827477d50884409bd43` |

`OfficialSchemaBundleIntegrityTest` recomputes these Git blob identifiers locally in CI. Any byte change to an official schema therefore requires an explicit manifest update and review.

## Updating the official schema bundle

1. Download the new production XSD package from the documented Sistema Nacional NFS-e production documentation page.
2. Create a new version directory; never overwrite an existing supported snapshot in place.
3. Copy the official XSD files byte-for-byte. Do not fix upstream schema defects in the reference files.
4. Add or update validators and representative contract tests for every XML document the library generates for that schema release.
5. Record the package name, publication date, source URL and Git blob identifiers in the new directory README.
6. Update the integrity-test manifest and run PHPUnit, static analysis, minimum-dependency and REUSE checks.
7. Document any deliberate compatibility caveat in the version README and in public migration notes.

When refreshing the official bundle, add a new version directory and update its own manifest instead of replacing this v1.01 snapshot in place.

49 changes: 49 additions & 0 deletions tests/Unit/Xml/OfficialSchemaBundleIntegrityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

// SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
// SPDX-License-Identifier: AGPL-3.0-or-later

declare(strict_types=1);

namespace LibreCodeCoop\NfsePHP\Tests\Unit\Xml;

use LibreCodeCoop\NfsePHP\Tests\TestCase;

/**
* Guards the vendored official schema snapshot against silent byte changes.
*/
final class OfficialSchemaBundleIntegrityTest extends TestCase
{
/**
* @var array<string, string>
*/
private const EXPECTED_GIT_BLOBS = [
'DPS_v1.01.xsd' => '39f440dd46db4e15a378b60910a3ac0baf19e476',
'tiposComplexos_v1.01.xsd' => '91f44b804ddcba93c65f7dea923ca4621c1dcd6a',
'tiposSimples_v1.01.xsd' => '6cf3dcb9c085e284a9b78b9a6a4c2688a95df5e9',
'xmldsig-core-schema.xsd' => '8a9c9139d0cb2c3497ce67942ba7d1e8528241d0',
'pedRegEvento_v1.01.xsd' => 'd8d3db9afdb2b79d6c32dd6d2ed727dcc6e22a6a',
'tiposEventos_v1.01.xsd' => '1a568683f6cb5e1ca65b5827477d50884409bd43',
];

public function testOfficialSchemaFilesMatchTheDocumentedSnapshot(): void
{
$schemaDirectory = dirname(__DIR__, 3) . '/references/schemas/nfse/1.01';

foreach (self::EXPECTED_GIT_BLOBS as $file => $expectedBlob) {
$path = $schemaDirectory . '/' . $file;
self::assertFileExists($path);

$contents = file_get_contents($path);
self::assertIsString($contents);

$actualBlob = sha1('blob ' . strlen($contents) . "\0" . $contents);

self::assertSame(
$expectedBlob,
$actualBlob,
'Official schema changed without an explicit integrity-manifest update: ' . $file,
);
}
}
}
Loading