From 6606438d525640f81b0ba2dcf2203eb865bf96cd Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 5 Sep 2022 16:22:12 -0500 Subject: [PATCH 01/23] Improve TestCase::installCertificate Now, it does not depends on the name of the certificate to perform a correct installation --- tests/CfdiUtilsTests/TestCase.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/CfdiUtilsTests/TestCase.php b/tests/CfdiUtilsTests/TestCase.php index 3600c54c..0b2d8ab9 100644 --- a/tests/CfdiUtilsTests/TestCase.php +++ b/tests/CfdiUtilsTests/TestCase.php @@ -2,6 +2,7 @@ namespace CfdiUtilsTests; +use CfdiUtils\Certificado\Certificado; use CfdiUtils\Certificado\SatCertificateNumber; use CfdiUtils\XmlResolver\XmlResolver; @@ -57,11 +58,13 @@ public function providerFullJoin(array $first, array ...$next): array protected function installCertificate(string $cerfile): string { - $certificateNumber = substr(basename($cerfile), 0, 20); - $satCertificateNumber = new SatCertificateNumber($certificateNumber); + $resolver = $this->newResolver(); - $cerRetriever = $this->newResolver()->newCerRetriever(); + $certificate = new Certificado('file://' . $cerfile); + $certificateNumber = $certificate->getSerial(); + $satCertificateNumber = new SatCertificateNumber($certificateNumber); + $cerRetriever = $resolver->newCerRetriever(); $installationPath = $cerRetriever->buildPath($satCertificateNumber->remoteUrl()); if (file_exists($installationPath)) { return $installationPath; From 580ba9a795b22a0b2c1ff1692c36a8fc48c0ca52 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 5 Dec 2022 13:04:22 -0600 Subject: [PATCH 02/23] Review Validate first-level objects and improve docblocks & return types --- src/CfdiUtils/Validate/Asserts.php | 6 +++--- src/CfdiUtils/Validate/CfdiValidatorTrait.php | 8 ++++---- src/CfdiUtils/Validate/Discoverer.php | 2 +- src/CfdiUtils/Validate/Status.php | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/CfdiUtils/Validate/Asserts.php b/src/CfdiUtils/Validate/Asserts.php index 3aafa5c6..02007280 100644 --- a/src/CfdiUtils/Validate/Asserts.php +++ b/src/CfdiUtils/Validate/Asserts.php @@ -62,7 +62,7 @@ public function putStatus(string $code, Status $status = null, string $explanati /** * Get and or set the flag that alerts about stop flow - * Consider this flag as: "Something was found, you chould not continue" + * Consider this flag as: "Something was found, you must not continue" * * @param bool|null $newValue value of the flag, if null then will not change the flag * @return bool the previous value of the flag @@ -96,7 +96,7 @@ public function hasWarnings(): bool * @param Status $status * @return Assert|null */ - public function getFirstStatus(Status $status) + public function getFirstStatus(Status $status): ?Assert { foreach ($this->asserts as $assert) { if ($status->equalsTo($assert->getStatus())) { @@ -127,7 +127,7 @@ public function get(string $code): Assert throw new \RuntimeException("There is no assert with code $code"); } - public function exists(string $code) + public function exists(string $code): bool { return array_key_exists($code, $this->asserts); } diff --git a/src/CfdiUtils/Validate/CfdiValidatorTrait.php b/src/CfdiUtils/Validate/CfdiValidatorTrait.php index 448713a8..d29122b7 100644 --- a/src/CfdiUtils/Validate/CfdiValidatorTrait.php +++ b/src/CfdiUtils/Validate/CfdiValidatorTrait.php @@ -33,11 +33,11 @@ public function __construct(XmlResolver $xmlResolver = null, XsltBuilderInterfac /** * Validate and return the asserts from the validation process. * This method can use a xml string and a NodeInterface, - * is your responsability that the node is the representation of the content. + * is your responsibility that the node is the representation of the content. * * @param string $xmlString * @param NodeInterface $node - * @return Asserts|\CfdiUtils\Validate\Assert[] + * @return Asserts|Assert[] */ public function validate(string $xmlString, NodeInterface $node): Asserts { @@ -63,7 +63,7 @@ public function validate(string $xmlString, NodeInterface $node): Asserts * Validate and return the asserts from the validation process based on a xml string * * @param string $xmlString - * @return Asserts|\CfdiUtils\Validate\Assert[] + * @return Asserts|Assert[] */ public function validateXml(string $xmlString): Asserts { @@ -74,7 +74,7 @@ public function validateXml(string $xmlString): Asserts * Validate and return the asserts from the validation process based on a node interface object * * @param NodeInterface $node - * @return Asserts|\CfdiUtils\Validate\Assert[] + * @return Asserts|Assert[] */ public function validateNode(NodeInterface $node): Asserts { diff --git a/src/CfdiUtils/Validate/Discoverer.php b/src/CfdiUtils/Validate/Discoverer.php index 7367139d..bf15f2cb 100644 --- a/src/CfdiUtils/Validate/Discoverer.php +++ b/src/CfdiUtils/Validate/Discoverer.php @@ -35,7 +35,7 @@ public function discoverInFolder(string $namespacePrefix, string $directoryPath) * @param string $filename * @return ValidatorInterface|null */ - public function discoverInFile(string $namespacePrefix, string $filename) + public function discoverInFile(string $namespacePrefix, string $filename): ?ValidatorInterface { $basename = basename($filename); $classname = $this->castNamespacePrefix($namespacePrefix) . substr($basename, 0, strlen($basename) - 4); diff --git a/src/CfdiUtils/Validate/Status.php b/src/CfdiUtils/Validate/Status.php index fe3cc909..20b484b1 100644 --- a/src/CfdiUtils/Validate/Status.php +++ b/src/CfdiUtils/Validate/Status.php @@ -4,7 +4,7 @@ /** * Status (immutable value object) - * Define the status used in an assert + * Define the status used in an assertion */ class Status { @@ -90,12 +90,12 @@ public function compareTo(self $status): int return $this->comparableValue($this) <=> $this->comparableValue($status); } - public static function comparableValue(self $status) + public static function comparableValue(self $status): int { return self::ORDER_MAP[$status->status]; } - public function __toString() + public function __toString(): string { return $this->status; } From 1a3ff0fb9b06b9a1aed93313813caf076ba5aaa9 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 5 Dec 2022 13:05:07 -0600 Subject: [PATCH 03/23] Refactor test/validate.php and allow to validate CFDI 3.3 & 4.0 --- tests/validate.php | 221 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 169 insertions(+), 52 deletions(-) diff --git a/tests/validate.php b/tests/validate.php index 0a13e821..0ddcbfff 100644 --- a/tests/validate.php +++ b/tests/validate.php @@ -1,60 +1,177 @@ getXmlResolver()->setLocalPath(''); - } - foreach ($files as $file) { - $xmlContent = strval(file_get_contents($file)); +exit(call_user_func(new class(...$argv) { + /** @var string */ + private $command; + + /** @var string[] */ + private $arguments; + + /** @var array */ + private $validators; + + private const SUCCESS = 0; + + private const ERROR = 1; + + private const FAILURE = 2; + + public function __construct(string $command, string ...$arguments) + { + $this->command = $command; + $this->arguments = $arguments; + $this->validators = [ + '3.3' => new CfdiValidator33(), + '4.0' => new CfdiValidator40(), + ]; + } + + public function __invoke(): int + { + if ([] !== array_intersect(['-h', '--help'], $this->arguments)) { + $this->printHelp(); + return self::SUCCESS; + } + + $files = []; + $noCache = false; + $clean = false; + foreach ($this->arguments as $argument) { + if (in_array($argument, ['-c', '--clean'], true)) { + $clean = true; + continue; + } + if ('--no-cache' === $argument) { + $noCache = true; + continue; + } + $files[] = $argument; + } + $files = array_unique(array_filter($files)); + if ([] === $files) { + printf("FAIL: No files were specified\n"); + return 2; + } + + if ($noCache) { + foreach ($this->validators as $validator) { + $validator->getXmlResolver()->setLocalPath(''); + } + } + + set_error_handler(function (int $number, string $message) { + throw new Error($message, $number); + }); + + $exitCode = self::SUCCESS; + foreach ($files as $file) { + printf("File: %s\n", $file); + try { + $asserts = $this->validateFile($file, $clean); + } catch (Throwable $exception) { + printf("FAIL: (%s) %s\n\n", get_class($exception), $exception->getMessage()); + $exitCode = self::FAILURE; + continue; + } + if (! $this->printAsserts($asserts)) { + $exitCode = self::ERROR; + } + printf("\n"); + } + + return $exitCode; + } + + private function printHelp(): void + { + $command = basename($this->command); + echo <<< EOH + $command Validates CFDI files + Syntax: + $command [-h|--help] [-c|--clean] [--no-cache] cfdi.xml ... + Arguments: + -h, --help Show this help + -c, --clean Clean CFDI before validation + --no-cache Tell resolver to not use local cache + cfdi.xml Files to check, as many as needed + Exit codes: + 0 - All files were validated with success + 1 - At least one file contains errors or warnings + 2 - At least one file produce an exception + + WARNING: This program can change at any time! Do not depend on this file or its results! + + + EOH; + } + + private function printAsserts(Asserts $asserts): bool + { + $warnings = $asserts->warnings(); + $errors = $asserts->errors(); + printf( + "Asserts: %s total, %s executed, %s ignored, %s success, %s warnings, %s errors.\n", + $asserts->count(), + $asserts->count() - count($asserts->nones()), + count($asserts->nones()), + count($asserts->oks()), + count($warnings), + count($errors) + ); + foreach ($warnings as $warning) { + $this->printAssert('WARNING', $warning); + } + foreach ($errors as $error) { + $this->printAssert('ERROR', $error); + } + return [] === $errors && [] === $warnings; + } + + private function printAssert(string $type, Assert $assert): void + { + $explanation = ''; + if ($assert->getExplanation()) { + $explanation = sprintf("\n%s%s", str_repeat(' ', mb_strlen($type) + 2), $assert->getExplanation()); + } + printf("%s: %s - %s%s\n", $type, $assert->getCode(), $assert->getTitle(), $explanation); + } + + private function validateFile(string $file, bool $clean): Asserts + { + $xmlContent = (string) file_get_contents($file); if ($clean) { - $xmlContent = \CfdiUtils\Cleaner\Cleaner::staticClean($xmlContent); + $xmlContent = Cleaner::staticClean($xmlContent); } - $asserts = $validator->validateXml($xmlContent); - print_r(array_filter([ - 'file' => $file, - 'asserts' => $asserts->count(), - 'hasErrors' => $asserts->hasErrors() ? 'yes' : 'no', - 'errors' => ($asserts->hasErrors()) ? $asserts->errors() : null, - 'hasWarnings' => $asserts->hasWarnings() ? 'yes' : 'no', - 'warnings' => ($asserts->hasWarnings()) ? $asserts->warnings() : null, - ])); + return $this->validateXmlContent($xmlContent); + } + + private function validateXmlContent(string $xmlContent): Asserts + { + $cfdi = Cfdi::newFromString($xmlContent); + return $this->validateCfdi($cfdi); } - return 0; -}, ...$argv)); + private function validateCfdi(Cfdi $cfdi): Asserts + { + $validator = $this->getValidatorForVersion($cfdi->getVersion()); + return $validator->validate($cfdi->getSource(), $cfdi->getNode()); + } + + /** @return CfdiValidator33|CfdiValidator40 */ + private function getValidatorForVersion(string $version) + { + if (! isset($this->validators[$version])) { + throw new Exception(sprintf('There is no validator for "%s"', $version)); + } + return $this->validators[$version]; + } +})); From 5e5879d66f37b47481a9186a924cc16f6abe9f0e Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 5 Dec 2022 13:23:31 -0600 Subject: [PATCH 04/23] Add indentation to nowdoc & heredoc --- .../Certificado/CertificadoTest.php | 22 ++++++------- tests/CfdiUtilsTests/Cleaner/CleanerTest.php | 32 +++++++++---------- .../PemPrivateKey/PemPrivateKeyTest.php | 12 +++---- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/CfdiUtilsTests/Certificado/CertificadoTest.php b/tests/CfdiUtilsTests/Certificado/CertificadoTest.php index 08c83cab..939b6f5b 100644 --- a/tests/CfdiUtilsTests/Certificado/CertificadoTest.php +++ b/tests/CfdiUtilsTests/Certificado/CertificadoTest.php @@ -13,17 +13,17 @@ public function testConstructWithValidExample() // openssl x509 -nameopt utf8,sep_multiline,lname -inform DER -noout -dates -serial -subject \ // -fingerprint -pubkey -in tests/assets/certs/EKU9003173C9.cer $expectedPublicKey = <<< EOD ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjdKXiqYHzi++YmEb9X6q -vqFWLCz1VEfxom2JhinPSJxxcuZWBejk2I5yCL5pDnUaG2xpQlMTkV/7S7JfGGvY -JumKO4R5zg0QSA7qdxiEhcwf/ekfSvzM2EDnLHDCKAQwEWsnJy78uxZTLzu/65VZ -7EgEcWUTvCs/GZJLI9s6XmKY2SMmv9+vfqBqkJNXE0ZB6OfSbyeE325P94iMn+B/ -yJ4vZwXvXGFqNDJyqG+ww7f77HYubQPJjLQPedy2qTcgmSAwkUEJVBjYA6mPf/Be -ZlL1YJHHM7CIBnb3/bzED0n944woio+4+rnMZdfhcCVpm74DZomlEf9KuJtq5u/J -RQIDAQAB ------END PUBLIC KEY----- - -EOD; + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjdKXiqYHzi++YmEb9X6q + vqFWLCz1VEfxom2JhinPSJxxcuZWBejk2I5yCL5pDnUaG2xpQlMTkV/7S7JfGGvY + JumKO4R5zg0QSA7qdxiEhcwf/ekfSvzM2EDnLHDCKAQwEWsnJy78uxZTLzu/65VZ + 7EgEcWUTvCs/GZJLI9s6XmKY2SMmv9+vfqBqkJNXE0ZB6OfSbyeE325P94iMn+B/ + yJ4vZwXvXGFqNDJyqG+ww7f77HYubQPJjLQPedy2qTcgmSAwkUEJVBjYA6mPf/Be + ZlL1YJHHM7CIBnb3/bzED0n944woio+4+rnMZdfhcCVpm74DZomlEf9KuJtq5u/J + RQIDAQAB + -----END PUBLIC KEY----- + + EOD; $cerfile = $this->utilAsset('certs/EKU9003173C9.cer'); $certificado = new Certificado($cerfile); diff --git a/tests/CfdiUtilsTests/Cleaner/CleanerTest.php b/tests/CfdiUtilsTests/Cleaner/CleanerTest.php index 9b5ff405..bc708b2e 100644 --- a/tests/CfdiUtilsTests/Cleaner/CleanerTest.php +++ b/tests/CfdiUtilsTests/Cleaner/CleanerTest.php @@ -202,23 +202,23 @@ public function testRemoveNonSatNSschemaLocationsRemoveEmptySchemaLocation() public function testCollapseComprobanteComplemento() { $source = <<<'EOT' - - - - - - -EOT; + + + + + + + EOT; $expected = <<<'EOT' - - - - - - - - -EOT; + + + + + + + + + EOT; $cleaner = new Cleaner($source); $cleaner->collapseComprobanteComplemento(); $this->assertXmlStringEqualsXmlString($expected, $cleaner->retrieveXml()); diff --git a/tests/CfdiUtilsTests/PemPrivateKey/PemPrivateKeyTest.php b/tests/CfdiUtilsTests/PemPrivateKey/PemPrivateKeyTest.php index 4d3bc4f9..3b120a44 100644 --- a/tests/CfdiUtilsTests/PemPrivateKey/PemPrivateKeyTest.php +++ b/tests/CfdiUtilsTests/PemPrivateKey/PemPrivateKeyTest.php @@ -130,12 +130,12 @@ public function testSign() $content = 'lorem ipsum'; $expectedSign = <<< EOC -CzjYgB2dOp4P76kYBSGymRJdQo9hjErCF+5mvoiVWVnvcV/eg9IkW+1DnOem5slYzU9+lzOo+I79wcOe -0gRtsmybGnViXxAQ8rr7YciFCoyqtKhxGjdgBpvO2NMT84n6U8ChYb8v7O/s4Gi5yTPj9D113rNsQGb8 -5nXerA+N6G6axy0F/IcUMZ6VPkDDjATcwjEj5A3q7qORG/l2cAKaV4nGKjn8V82bZ40ys7PGvFfZfirZ -BeKg1QPUqf2fpgVI6wf/IM4YRD6ZbTgtFiYH30/dlzowZTAR1NMHJXa4uxCdTY7mQVekTw0FNDxrAZr/ -5lLezLMMyEezIz+EQKgAvg== -EOC; + CzjYgB2dOp4P76kYBSGymRJdQo9hjErCF+5mvoiVWVnvcV/eg9IkW+1DnOem5slYzU9+lzOo+I79wcOe + 0gRtsmybGnViXxAQ8rr7YciFCoyqtKhxGjdgBpvO2NMT84n6U8ChYb8v7O/s4Gi5yTPj9D113rNsQGb8 + 5nXerA+N6G6axy0F/IcUMZ6VPkDDjATcwjEj5A3q7qORG/l2cAKaV4nGKjn8V82bZ40ys7PGvFfZfirZ + BeKg1QPUqf2fpgVI6wf/IM4YRD6ZbTgtFiYH30/dlzowZTAR1NMHJXa4uxCdTY7mQVekTw0FNDxrAZr/ + 5lLezLMMyEezIz+EQKgAvg== + EOC; $sign = chunk_split(base64_encode($privateKey->sign($content, OPENSSL_ALGO_SHA256)), 80, "\n"); $this->assertEquals($expectedSign, rtrim($sign)); } From 5bfebcc8d3859d9d2d4fd5fbd2403bcdbc681745 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 5 Dec 2022 17:40:41 -0600 Subject: [PATCH 05/23] Fix test on certificate name This value is different from on different openssl versions. 3.x: uses quoted slashes 1.1.x: does not use quoted slashes --- tests/CfdiUtilsTests/Certificado/CertificadoTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CfdiUtilsTests/Certificado/CertificadoTest.php b/tests/CfdiUtilsTests/Certificado/CertificadoTest.php index 939b6f5b..0cf4062b 100644 --- a/tests/CfdiUtilsTests/Certificado/CertificadoTest.php +++ b/tests/CfdiUtilsTests/Certificado/CertificadoTest.php @@ -37,7 +37,7 @@ public function testConstructWithValidExample() '/serialNumber= / XIQB891116MGRMZR05', '/OU=Escuela Kemper Urgate', ]); - $this->assertSame($certificateName, $certificado->getCertificateName()); + $this->assertSame($certificateName, str_replace('\/', '/', $certificado->getCertificateName())); $this->assertSame('ESCUELA KEMPER URGATE SA DE CV', $certificado->getName()); $this->assertSame('EKU9003173C9', $certificado->getRfc()); $this->assertSame('30001000000400002434', $certificado->getSerial()); From e4283f00f5153cb53b6831418786692fd7b61d55 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 5 Dec 2022 17:41:21 -0600 Subject: [PATCH 06/23] Add getCertificateName phpdoc & fix grammar and typos --- src/CfdiUtils/Certificado/Certificado.php | 24 ++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/CfdiUtils/Certificado/Certificado.php b/src/CfdiUtils/Certificado/Certificado.php index b0d10cb0..0d007af9 100644 --- a/src/CfdiUtils/Certificado/Certificado.php +++ b/src/CfdiUtils/Certificado/Certificado.php @@ -41,7 +41,7 @@ class Certificado * * @param string $filename Allows filename or certificate contents (PEM or DER) * @param OpenSSL|null $openSSL - * @throws \UnexpectedValueException when the certificate does not exists or is not readable + * @throws \UnexpectedValueException when the certificate does not exist or is not readable * @throws \UnexpectedValueException when cannot read the certificate or is empty * @throws \RuntimeException when cannot parse the certificate or is empty * @throws \RuntimeException when cannot get serialNumberHex or serialNumber from certificate @@ -100,7 +100,7 @@ private function extractPemCertificate(string $contents): string { $openssl = $this->getOpenSSL(); $decoded = @base64_decode($contents, true) ?: ''; - if ('' !== $decoded && $contents === base64_encode($decoded)) { // is a one liner certificate + if ('' !== $decoded && $contents === base64_encode($decoded)) { // is a one-liner certificate $doubleEncoded = $openssl->readPemContents($decoded)->certificate(); if ('' !== $doubleEncoded) { return $doubleEncoded; @@ -129,9 +129,9 @@ private function obtainPemCertificate(string $contents): string * * @return bool * - * @throws \UnexpectedValueException if the file does not exists or is not readable + * @throws \UnexpectedValueException if the file does not exist or is not readable * @throws \UnexpectedValueException if the file is not a PEM private key - * @throws \RuntimeException if cannot open the private key file + * @throws \RuntimeException if the private key file cannot be opened */ public function belongsTo(string $pemKeyFile, string $passPhrase = ''): bool { @@ -165,6 +165,12 @@ public function getRfc(): string return $this->rfc; } + /** + * Certificate name value as returned by openssl. + * In come cases (openssl version 3) it contains quoted slashes (\/) + * + * @return string + */ public function getCertificateName(): string { return $this->certificateName; @@ -180,7 +186,7 @@ public function getName(): string } /** - * Certificate serial number as ASCII, this data is in the format required by CFDI + * Return the certificate serial number ASCII formatted, this data is in the format required by CFDI * @return string */ public function getSerial(): string @@ -221,7 +227,7 @@ public function getPubkey(): string } /** - * Place where the certificate was when loaded, it might not exists on the file system + * Place where the certificate was when loaded, it might not exist on the file system * @return string */ public function getFilename(): string @@ -256,7 +262,7 @@ public function getPemContentsOneLine(): string * * @return bool * - * @throws \RuntimeException if cannot open the public key from certificate + * @throws \RuntimeException if the public key on the certificate cannot be opened * @throws \RuntimeException if openssl report an error */ public function verify(string $data, string $signature, int $algorithm = OPENSSL_ALGO_SHA256): bool @@ -281,7 +287,7 @@ public function verify(string $data, string $signature, int $algorithm = OPENSSL /** * @param string $filename - * @throws \UnexpectedValueException when the file does not exists or is not readable + * @throws \UnexpectedValueException when the file does not exist or is not readable * @return void */ protected function assertFileExists(string $filename) @@ -289,7 +295,7 @@ protected function assertFileExists(string $filename) $exists = false; $previous = null; try { - if (boolval(preg_match('/[[:cntrl:]]/', $filename))) { + if (preg_match('/[[:cntrl:]]/', $filename)) { $filename = '(invalid file name)'; throw new \RuntimeException('The file name contains control characters, it might be a DER content'); } From 459a57d387224ded71c80207b61071b5653f32cf Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 08:35:51 -0600 Subject: [PATCH 07/23] Remove deprecated ::set-output & ::save-state --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4155fdfe..9fec804c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: - name: Get composer cache directory id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies uses: actions/cache@v2 @@ -109,7 +109,7 @@ jobs: - name: Get composer cache directory id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies uses: actions/cache@v2 From 6711c9a33da2f0c339bd9afe77e51cf93491136a Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 09:16:55 -0600 Subject: [PATCH 08/23] Install dependencies running on nektos/act --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9fec804c..fd72283b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -90,6 +90,12 @@ jobs: with: fetch-depth: 0 + - name: Install dependencies running on nektos/act + if: github.actor == 'nektos/act' + run: | + sudo apt-get update -y -qq + sudo apt-get install -y -qq zstd wget + # see https://github.com/marketplace/actions/setup-php-action - name: Setup PHP uses: shivammathur/setup-php@v2 From 3031503295ad61dd4bb47ec77edb5eac518457a7 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 09:18:19 -0600 Subject: [PATCH 09/23] When install libsaxonb-java do not check for matrix Matrix is not used on full-build job --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd72283b..fdc452ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -107,8 +107,7 @@ jobs: env: fail-fast: true - - name: Install libsaxonb-java on linux - if: matrix.operating-systems == 'ubuntu-latest' + - name: Install libsaxonb-java run: | sudo apt-get update -y -qq sudo apt-get install -y -qq default-jre libsaxonb-java From f64c1165c4a209702ef3f0b34364e0e837623220 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 09:24:01 -0600 Subject: [PATCH 10/23] Refactor to return exit code 1 on error while wget or unzip --- tests/resource-sat-xml-download | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/resource-sat-xml-download b/tests/resource-sat-xml-download index 4f8abb05..025eecee 100755 --- a/tests/resource-sat-xml-download +++ b/tests/resource-sat-xml-download @@ -7,15 +7,25 @@ else fi WORKDIR="$(mktemp --directory)" +SOURCEFILE=https://github.com/phpcfdi/resources-sat-xml/archive/master.zip ZIPFILE="$WORKDIR/resources-sat-xml.zip" # download latest archive from github as resources-sat-xml.zip -echo "Downloading https://github.com/phpcfdi/resources-sat-xml/archive/master.zip to $ZIPFILE" -wget -O "$ZIPFILE" https://github.com/phpcfdi/resources-sat-xml/archive/master.zip +echo "Downloading $SOURCEFILE to $ZIPFILE" +wget -O "$ZIPFILE" "$SOURCEFILE" +if [ $? -ne 0 ]; then + echo "Error while downloading $SOURCEFILE" >&2 + exit 1 +fi # unzip the "resources" folder contents and place then into my-resources echo "Extract resources from $ZIPFILE" unzip "$ZIPFILE" 'resources-sat-xml-master/resources/*' -d "$WORKDIR" +wget -O "$ZIPFILE" "$SOURCEFILE" +if [ $? -ne 0 ]; then + echo "Error while extract resources from $ZIPFILE" >&2 + exit 1 +fi echo "Copy $WORKDIR/resources-sat-xml-master/resources/ to $DESTINATION" rm -rf "$DESTINATION/resources/www.sat.gob.mx" From 4817bf0bd666844f1cb11a8d74fca76687b8f178 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 09:24:20 -0600 Subject: [PATCH 11/23] Simplify extensions --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fdc452ab..cf45908e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} - extensions: libxml, dom, xsl, simplexml, mbstring, openssl, soap, iconv, json, intl, fileinfo + extensions: soap coverage: none tools: composer:v2 env: @@ -101,7 +101,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: "8.0" - extensions: libxml, dom, xsl, simplexml, mbstring, openssl, soap, iconv, json, intl, fileinfo + extensions: soap coverage: xdebug tools: composer:v2, cs2pr env: From 6a5a34e45687079aa34fd10868b7e6c1d1e12ec5 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 09:33:04 -0600 Subject: [PATCH 12/23] Refactor - List actions - Remove whitespace --- .github/workflows/build.yml | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cf45908e..f0f5865b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,33 +9,32 @@ on: schedule: - cron: '0 16 * * 0' # sunday 16:00 +# Actions +# shivammathur/setup-php@v2 - https://github.com/marketplace/actions/setup-php-action +# nosborn/github-action-markdown-cli@v1.1.1 https://github.com/marketplace/actions/markdownlint-cli +# Tiryoh/actions-mkdocs@v0 https://github.com/marketplace/actions/mkdocs-action + jobs: # this job performs phpunit tests on linux, windows and all php supported versions tests: name: PHP ${{ matrix.php-versions }} on ${{ matrix.operating-systems }} runs-on: ${{ matrix.operating-systems }} - strategy: matrix: operating-systems: [ "ubuntu-latest", "windows-latest" ] php-versions: [ '7.3', '7.4', '8.0', '8.1' ] - steps: - name: Checkout uses: actions/checkout@v3 - - name: Install libsaxonb-java on linux if: matrix.operating-systems == 'ubuntu-latest' run: | sudo apt-get update -y -qq sudo apt-get install -y -qq default-jre libsaxonb-java - - name: Install saxonhe on windows if: matrix.operating-systems == 'windows-latest' run: choco install --ignore-checksums --no-progress --yes saxonhe - - # see https://github.com/marketplace/actions/setup-php-action - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -45,34 +44,28 @@ jobs: tools: composer:v2 env: fail-fast: true - - name: Get composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - name: Install SAT XML resources shell: bash run: | git clone --depth 1 https://github.com/phpcfdi/resources-sat-xml resources-sat-xml-cloned mv resources-sat-xml-cloned/resources build/resources rm -r -f resources-sat-xml-cloned - - name: Install project dependencies run: | composer remove squizlabs/php_codesniffer friendsofphp/php-cs-fixer phpstan/phpstan --dev --no-interaction --no-progress --no-update composer upgrade --no-interaction --no-progress --prefer-dist - - name: Tests (phpunit) on linux if: matrix.operating-systems == 'ubuntu-latest' run: vendor/bin/phpunit --testdox --verbose - - name: Tests (phpunit) on windows if: matrix.operating-systems == 'windows-latest' run: vendor/bin/phpunit --testdox --verbose @@ -83,20 +76,16 @@ jobs: full-build: name: Full build runs-on: "ubuntu-latest" - steps: - name: Checkout uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Install dependencies running on nektos/act if: github.actor == 'nektos/act' run: | sudo apt-get update -y -qq sudo apt-get install -y -qq zstd wget - - # see https://github.com/marketplace/actions/setup-php-action - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -106,55 +95,41 @@ jobs: tools: composer:v2, cs2pr env: fail-fast: true - - name: Install libsaxonb-java run: | sudo apt-get update -y -qq sudo apt-get install -y -qq default-jre libsaxonb-java - - name: Get composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - name: Install SAT XML resources run: bash tests/resource-sat-xml-download build/ - - name: Install project dependencies run: composer upgrade --no-interaction --no-progress --prefer-dist - - # https://github.com/marketplace/actions/markdown-cli - name: Code style (markdownlint-cli) uses: nosborn/github-action-markdown-cli@v1.1.1 with: files: '*.md docs/' config_file: '.markdownlint.json' - - name: Code style (phpcs) run: vendor/bin/phpcs -q --report=checkstyle src/ tests/ | cs2pr - - name: Code style (php-cs-fixer) run: vendor/bin/php-cs-fixer fix --dry-run --format=checkstyle | cs2pr - - name: Tests (phpunit) run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml - - name: Code analysis (phpstan) run: vendor/bin/phpstan analyse --no-progress --verbose src/ tests/ - - name: Upload code coverage to scrutinizer run: | mkdir -p build/scrutinizer composer require scrutinizer/ocular:dev-master --working-dir=build/scrutinizer --no-progress php build/scrutinizer/vendor/bin/ocular code-coverage:upload -vvv --no-interaction --format=php-clover build/coverage-clover.xml - - # see https://github.com/marketplace/actions/mkdocs-action - name: Run mkdocs uses: Tiryoh/actions-mkdocs@v0 with: From eec18571c6b5df8a9e34ef9ff83194cb0ea79c8b Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 09:33:28 -0600 Subject: [PATCH 13/23] Install dependencies running on nektos/act on tests job --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f0f5865b..2d0a8bcd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,6 +27,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + - name: Install dependencies running on nektos/act + if: matrix.operating-systems == 'ubuntu-latest' && github.actor == 'nektos/act' + run: | + sudo apt-get update -y -qq + sudo apt-get install -y -qq zstd wget - name: Install libsaxonb-java on linux if: matrix.operating-systems == 'ubuntu-latest' run: | From b5875e74e01c8446451b6d7a294859645686cc6e Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 10:14:17 -0600 Subject: [PATCH 14/23] Split full build to individual jobs --- .github/workflows/build.yml | 111 +++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d0a8bcd..0b93b75f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,93 @@ on: jobs: - # this job performs phpunit tests on linux, windows and all php supported versions + phpcs: + name: Code style (phpcs) + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 # see https://github.com/marketplace/actions/setup-php-action + with: + php-version: '8.1' + coverage: none + tools: cs2pr, phpcs + env: + fail-fast: true + - name: Code style (phpcs) + run: phpcs -q --report=checkstyle src/ tests/ | cs2pr + + php-cs-fixer: + name: Code style (php-cs-fixer) + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 # see https://github.com/marketplace/actions/setup-php-action + with: + php-version: '8.1' + coverage: none + tools: cs2pr, php-cs-fixer + env: + fail-fast: true + - name: Code style (php-cs-fixer) + run: php-cs-fixer fix --dry-run --format=checkstyle | cs2pr + + markdownlint: + name: Markdown style (markdownlint) + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Code style (markdownlint-cli) + uses: nosborn/github-action-markdown-cli@v3.2.0 + with: + files: '*.md docs/' + config_file: '.markdownlint.json' + + mkdocs: + name: Test docs building + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Run mkdocs + uses: Tiryoh/actions-mkdocs@v0 + with: + mkdocs_version: 'latest' + configfile: 'mkdocs.yml' + + phpstan: + name: Code analysis (phpstan) + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: soap + coverage: none + tools: composer:v2, phpstan + env: + fail-fast: true + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install project dependencies + run: composer upgrade --no-interaction --no-progress --prefer-dist + - name: PHPStan + run: phpstan analyse --no-progress --verbose src/ tests/ + tests: name: PHP ${{ matrix.php-versions }} on ${{ matrix.operating-systems }} runs-on: ${{ matrix.operating-systems }} @@ -77,9 +163,8 @@ jobs: env: saxonb-path: 'C:\ProgramData\chocolatey\bin\SaxonHE\bin\Transform.exe' - # this job performs a full build (check style, testing with coverage, code analysis and build docs) - full-build: - name: Full build + code-coverage: + name: Code coverage runs-on: "ubuntu-latest" steps: - name: Checkout @@ -117,26 +202,10 @@ jobs: run: bash tests/resource-sat-xml-download build/ - name: Install project dependencies run: composer upgrade --no-interaction --no-progress --prefer-dist - - name: Code style (markdownlint-cli) - uses: nosborn/github-action-markdown-cli@v1.1.1 - with: - files: '*.md docs/' - config_file: '.markdownlint.json' - - name: Code style (phpcs) - run: vendor/bin/phpcs -q --report=checkstyle src/ tests/ | cs2pr - - name: Code style (php-cs-fixer) - run: vendor/bin/php-cs-fixer fix --dry-run --format=checkstyle | cs2pr - - name: Tests (phpunit) + - name: Create code coverage (phpunit) run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml - - name: Code analysis (phpstan) - run: vendor/bin/phpstan analyse --no-progress --verbose src/ tests/ - name: Upload code coverage to scrutinizer run: | mkdir -p build/scrutinizer composer require scrutinizer/ocular:dev-master --working-dir=build/scrutinizer --no-progress php build/scrutinizer/vendor/bin/ocular code-coverage:upload -vvv --no-interaction --format=php-clover build/coverage-clover.xml - - name: Run mkdocs - uses: Tiryoh/actions-mkdocs@v0 - with: - mkdocs_version: 'latest' - configfile: 'mkdocs.yml' From 9ba7a12f624ef5e673b881c70ddff131cd22abdb Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 10:25:18 -0600 Subject: [PATCH 15/23] Merge code-coverage and tests jobs --- .github/workflows/build.yml | 47 +++---------------------------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b93b75f..7d6b85d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -131,7 +131,7 @@ jobs: with: php-version: ${{ matrix.php-versions }} extensions: soap - coverage: none + coverage: xdebug tools: composer:v2 env: fail-fast: true @@ -156,55 +156,14 @@ jobs: composer upgrade --no-interaction --no-progress --prefer-dist - name: Tests (phpunit) on linux if: matrix.operating-systems == 'ubuntu-latest' - run: vendor/bin/phpunit --testdox --verbose + run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml - name: Tests (phpunit) on windows if: matrix.operating-systems == 'windows-latest' run: vendor/bin/phpunit --testdox --verbose env: saxonb-path: 'C:\ProgramData\chocolatey\bin\SaxonHE\bin\Transform.exe' - - code-coverage: - name: Code coverage - runs-on: "ubuntu-latest" - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Install dependencies running on nektos/act - if: github.actor == 'nektos/act' - run: | - sudo apt-get update -y -qq - sudo apt-get install -y -qq zstd wget - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.0" - extensions: soap - coverage: xdebug - tools: composer:v2, cs2pr - env: - fail-fast: true - - name: Install libsaxonb-java - run: | - sudo apt-get update -y -qq - sudo apt-get install -y -qq default-jre libsaxonb-java - - name: Get composer cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install SAT XML resources - run: bash tests/resource-sat-xml-download build/ - - name: Install project dependencies - run: composer upgrade --no-interaction --no-progress --prefer-dist - - name: Create code coverage (phpunit) - run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml - name: Upload code coverage to scrutinizer + if: matrix.operating-systems == 'ubuntu-latest' run: | mkdir -p build/scrutinizer composer require scrutinizer/ocular:dev-master --working-dir=build/scrutinizer --no-progress From 3a42161de1971738c898d7b07b978dc632277d10 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 10:29:08 -0600 Subject: [PATCH 16/23] Split tests to tests-windows and tests-windows --- .github/workflows/build.yml | 62 ++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7d6b85d7..753f3287 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,29 +103,24 @@ jobs: - name: PHPStan run: phpstan analyse --no-progress --verbose src/ tests/ - tests: - name: PHP ${{ matrix.php-versions }} on ${{ matrix.operating-systems }} + tests-linux: + name: PHP ${{ matrix.php-versions }} on Linux runs-on: ${{ matrix.operating-systems }} strategy: matrix: - operating-systems: [ "ubuntu-latest", "windows-latest" ] php-versions: [ '7.3', '7.4', '8.0', '8.1' ] steps: - name: Checkout uses: actions/checkout@v3 - name: Install dependencies running on nektos/act - if: matrix.operating-systems == 'ubuntu-latest' && github.actor == 'nektos/act' + if: github.actor == 'nektos/act' run: | sudo apt-get update -y -qq sudo apt-get install -y -qq zstd wget - name: Install libsaxonb-java on linux - if: matrix.operating-systems == 'ubuntu-latest' run: | sudo apt-get update -y -qq sudo apt-get install -y -qq default-jre libsaxonb-java - - name: Install saxonhe on windows - if: matrix.operating-systems == 'windows-latest' - run: choco install --ignore-checksums --no-progress --yes saxonhe - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -155,16 +150,53 @@ jobs: composer remove squizlabs/php_codesniffer friendsofphp/php-cs-fixer phpstan/phpstan --dev --no-interaction --no-progress --no-update composer upgrade --no-interaction --no-progress --prefer-dist - name: Tests (phpunit) on linux - if: matrix.operating-systems == 'ubuntu-latest' run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml - - name: Tests (phpunit) on windows - if: matrix.operating-systems == 'windows-latest' - run: vendor/bin/phpunit --testdox --verbose - env: - saxonb-path: 'C:\ProgramData\chocolatey\bin\SaxonHE\bin\Transform.exe' - name: Upload code coverage to scrutinizer - if: matrix.operating-systems == 'ubuntu-latest' run: | mkdir -p build/scrutinizer composer require scrutinizer/ocular:dev-master --working-dir=build/scrutinizer --no-progress php build/scrutinizer/vendor/bin/ocular code-coverage:upload -vvv --no-interaction --format=php-clover build/coverage-clover.xml + + tests-windows: + name: PHP ${{ matrix.php-versions }} on Windows + runs-on: ${{ matrix.operating-systems }} + strategy: + matrix: + php-versions: [ '7.3', '7.4', '8.0', '8.1' ] + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install saxonhe + run: choco install --ignore-checksums --no-progress --yes saxonhe + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: soap + coverage: none + tools: composer:v2 + env: + fail-fast: true + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install SAT XML resources + shell: bash + run: | + git clone --depth 1 https://github.com/phpcfdi/resources-sat-xml resources-sat-xml-cloned + mv resources-sat-xml-cloned/resources build/resources + rm -r -f resources-sat-xml-cloned + - name: Install project dependencies + run: | + composer remove squizlabs/php_codesniffer friendsofphp/php-cs-fixer phpstan/phpstan --dev --no-interaction --no-progress --no-update + composer upgrade --no-interaction --no-progress --prefer-dist + - name: Tests (phpunit) + run: vendor/bin/phpunit --testdox --verbose + env: + saxonb-path: 'C:\ProgramData\chocolatey\bin\SaxonHE\bin\Transform.exe' From 9a6f547ce6a3dae0fe9189c85f6c3dd79bcb1cb9 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 10:45:12 -0600 Subject: [PATCH 17/23] Version 2.23.4 proposal --- docs/CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c33d0bf5..5284769a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -32,6 +32,23 @@ - Merge methods from `\CfdiUtils\Nodes\NodeHasValueInterface` into `\CfdiUtils\Nodes\NodeInterface`. - Remove deprecated constant `CfdiUtils\Retenciones\Retenciones::RET_NAMESPACE`. +## Version 2.23.4 2022-12-05 + +This is a maintenance release fo fix the continuous integration workflow and append pending development changes. + +- Fix test `CertificadoTest::testConstructWithValidExample()` to allow quoted slashes on name. +- Add *phpdoc* to the method `Certificate::getCertificateName()`. + The value can contain quoted slashes `\/` depending on the OpenSSL version. +- Update script `tests/validate.php` to validate CFDI 3.3 or CFDI 4.0. +- Add return types to some methods: + - `Status::comparableValue` and `Status::__toString`. + - `Discoverer::discoverInFile`. +- Improve `TestCase::installCertificate()`: It doesn't depend on the certificate's file name to install correctly. +- Update GitHub build workflow: + - Update GH Workflows: Remove deprecated `::set-output` & `::save-state`. + - Split **full build** actions to individual jobs. + - Split Windows and Linux testing. + ## Version 2.23.3 2022-08-11 Fix CFDI 4.0, must include `Comprobante/Impuestos/Traslados/Traslado@TipoFactor=Exento` when exists at least one From 6d80aa8fa42811c2c025a139b6ff2d59d5564cca Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 10:54:41 -0600 Subject: [PATCH 18/23] Fix runs-on for tests-linux & tests-windows --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a2bec463..1fa1ff92 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,7 +105,7 @@ jobs: tests-linux: name: PHP ${{ matrix.php-versions }} on Linux - runs-on: ${{ matrix.operating-systems }} + runs-on: "ubuntu-latest" strategy: matrix: php-versions: [ '7.3', '7.4', '8.0', '8.1' ] @@ -157,7 +157,7 @@ jobs: tests-windows: name: PHP ${{ matrix.php-versions }} on Windows - runs-on: ${{ matrix.operating-systems }} + runs-on: "windows-latest" strategy: matrix: php-versions: [ '7.3', '7.4', '8.0', '8.1' ] From 68971d9859cd91308861a0a4b9010887dd15b7eb Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 10:55:05 -0600 Subject: [PATCH 19/23] Update version 2.23.4 date --- docs/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 5284769a..47a6c002 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -32,7 +32,7 @@ - Merge methods from `\CfdiUtils\Nodes\NodeHasValueInterface` into `\CfdiUtils\Nodes\NodeInterface`. - Remove deprecated constant `CfdiUtils\Retenciones\Retenciones::RET_NAMESPACE`. -## Version 2.23.4 2022-12-05 +## Version 2.23.4 2022-12-07 This is a maintenance release fo fix the continuous integration workflow and append pending development changes. From 3947102caca0c71bee0b7801ddd30470d07a82ec Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 11:01:40 -0600 Subject: [PATCH 20/23] Add `shell: bash` to get composer cache directory on windows --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fa1ff92..89c82b87 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,7 +104,7 @@ jobs: run: phpstan analyse --no-progress --verbose src/ tests/ tests-linux: - name: PHP ${{ matrix.php-versions }} on Linux + name: Test PHP ${{ matrix.php-versions }} on Linux runs-on: "ubuntu-latest" strategy: matrix: @@ -156,7 +156,7 @@ jobs: php build/scrutinizer/vendor/bin/ocular code-coverage:upload -vvv --no-interaction --format=php-clover build/coverage-clover.xml tests-windows: - name: PHP ${{ matrix.php-versions }} on Windows + name: Tests PHP ${{ matrix.php-versions }} on Windows runs-on: "windows-latest" strategy: matrix: @@ -177,6 +177,7 @@ jobs: fail-fast: true - name: Get composer cache directory id: composer-cache + shell: bash run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies uses: actions/cache@v2 From 0ec71bdb4fb6ad1cd494ba4edafe3324e411fb5d Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 11:04:38 -0600 Subject: [PATCH 21/23] Add git fetch depth to allow uploads to scrutinizer --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 89c82b87..b79395a3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -112,6 +112,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + with: + fetch-depth: 0 # required for scrutinizer - name: Install libsaxonb-java on linux run: | sudo apt-get update -y -qq From a1b0ee4c2d001083b036434a31bf03f980f944d4 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 11:07:48 -0600 Subject: [PATCH 22/23] Use actions/cache@v3 instead of v2 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b79395a3..ac64666d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,7 +134,7 @@ jobs: id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -182,7 +182,7 @@ jobs: shell: bash run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} From f9f4d078945ec0960ba7359b51931018ed529d4e Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Wed, 7 Dec 2022 11:34:08 -0600 Subject: [PATCH 23/23] Fix extensions on setup-php according to operating system - linux https://github.com/shivammathur/setup-php/wiki/Php-extensions-loaded-on-ubuntu-22.04 - windows https://github.com/shivammathur/setup-php/wiki/Php-extensions-loaded-on-windows-2022 --- .github/workflows/build.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ac64666d..93d45118 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -84,7 +84,6 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '8.1' - extensions: soap coverage: none tools: composer:v2, phpstan env: @@ -125,7 +124,6 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} - extensions: soap coverage: xdebug tools: composer:v2 env: @@ -172,7 +170,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} - extensions: soap + extensions: soap, intl, xsl, fileinfo coverage: none tools: composer:v2 env: