Add GitHub CI template support

This commit is contained in:
netkas 2024-09-23 18:56:28 -04:00
parent b30ddbdc28
commit 80a019452f
4 changed files with 279 additions and 6 deletions

View file

@ -0,0 +1,68 @@
<?php
/*
* Copyright (c) Nosial 2022-2024, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension\Templates;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Managers\ProjectManager;
use ncc\Utilities\IO;
class GitHubWorkflowTemplate
{
/**
* @inheritDoc
* @param ProjectManager $project_manager
* @throws IOException
* @throws PathNotFoundException
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
self::writeCiTemplate($project_manager);
}
/**
* Writes the Makefile to the project directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeCiTemplate(ProjectManager $project_manager): void
{
$ci_dir = $project_manager->getProjectPath() . DIRECTORY_SEPARATOR . '.github' . DIRECTORY_SEPARATOR . 'workflows';
if(!file_exists($ci_dir))
{
mkdir($ci_dir, 0777, true);
}
IO::fwrite(
$ci_dir . DIRECTORY_SEPARATOR . 'ncc_workflow.yml',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'github_ci.yml.tpl')
)
);
}
}

View file

@ -0,0 +1,158 @@
name: CI
on:
push:
branches:
- '**'
release:
types: [created]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container:
image: php:8.3
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
apt update -yqq
apt install git libpq-dev libzip-dev zip make wget gnupg -yqq
- name: Install phive
run: |
wget -O phive.phar https://phar.io/releases/phive.phar
wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc
gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79
gpg --verify phive.phar.asc phive.phar
chmod +x phive.phar
mv phive.phar /usr/local/bin/phive
- name: Install phab
run: |
phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C
- name: Install latest version of NCC
run: |
git clone https://git.n64.cc/nosial/ncc.git
cd ncc
make redist
NCC_DIR=$(find build/ -type d -name "ncc_*" | head -n 1)
if [ -z "$NCC_DIR" ]; then
echo "NCC build directory not found"
exit 1
fi
php "$NCC_DIR/INSTALL" --auto
cd .. && rm -rf ncc
- name: Build project
run: |
ncc build --config release --log-level debug
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: %ASSEMBLY.NAME%_build
path: build/release/%ASSEMBLY.PACKAGE%.ncc
test:
needs: build
runs-on: ubuntu-latest
container:
image: php:8.3
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check for phpunit.xml
id: file_check
run: |
if [ -f phpunit.xml ]; then
echo "::set-output name=exists::true"
else
echo "::set-output name=exists::false"
fi
- name: Skip if no phpunit.xml
if: steps.file_check.outputs.exists == 'false'
run: exit 78
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: %ASSEMBLY.NAME%_build
path: %ASSEMBLY.NAME%_build # Adjust this to download the artifact directly under '%ASSEMBLY.NAME%_build'
- name: Install dependencies
run: |
apt update -yqq
apt install git libpq-dev libzip-dev zip make wget gnupg -yqq
curl -sSLf -o /usr/local/bin/install-php-extensions https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions
chmod +x /usr/local/bin/install-php-extensions
install-php-extensions zip
- name: Install phive
run: |
wget -O phive.phar https://phar.io/releases/phive.phar
wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc
gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79
gpg --verify phive.phar.asc phive.phar
chmod +x phive.phar
mv phive.phar /usr/local/bin/phive
- name: Install phab
run: |
phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C
- name: Install latest version of NCC
run: |
git clone https://git.n64.cc/nosial/ncc.git
cd ncc
make redist
NCC_DIR=$(find build/ -type d -name "ncc_*" | head -n 1)
if [ -z "$NCC_DIR" ]; then
echo "NCC build directory not found"
exit 1
fi
php "$NCC_DIR/INSTALL" --auto
cd .. && rm -rf ncc
- name: Install NCC packages
run: |
ncc package install --package="%ASSEMBLY.NAME%_build/%ASSEMBLY.PACKAGE%.ncc" --build-source --reinstall -y --log-level debug
- name: Run PHPUnit tests
run: |
wget https://phar.phpunit.de/phpunit-11.3.phar
php phpunit-11.3.phar --configuration phpunit.xml
release:
needs: [build, test]
permissions: write-all
runs-on: ubuntu-latest
container:
image: php:8.3
if: github.event_name == 'release'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: %ASSEMBLY.NAME%_build
path: %ASSEMBLY.NAME%_build
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
%ASSEMBLY.NAME%_build/%ASSEMBLY.PACKAGE%.ncc
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -53,4 +53,40 @@
* Template that combines PHP_LIBRARY, PHP_MAKE, PHP_UNIT and PHP_CLI in one
*/
case PHP_CLI_FULL = 'phpcli_full';
/**
* Template that applies a GitHub workflow CI that builds the project, tests the project and creates
* automatic builds for releases
*/
case PHP_GITHUB_CI = 'phpci_github';
/**
* Suggests the closest matching `ProjectTemplates` instance based on the given input string.
*
* @param string $input The input string to compare against.
* @return ProjectTemplates|null The closest matching `ProjectTemplates` instance, or null if no close match is found.
*/
public static function suggest(string $input): ?ProjectTemplates
{
$closest = null;
$shortest_distance = -1;
foreach (self::cases() as $case)
{
$distance = levenshtein($input, $case->value);
if ($distance === 0)
{
return $case;
}
if ($shortest_distance === -1 || $distance < $shortest_distance)
{
$closest = $case;
$shortest_distance = $distance;
}
}
return $closest ?: null;
}
}

View file

@ -29,6 +29,7 @@
use ncc\Classes\PhpExtension\ExecutableCompiler;
use ncc\Classes\PhpExtension\NccCompiler;
use ncc\Classes\PhpExtension\Templates\CliTemplate;
use ncc\Classes\PhpExtension\Templates\GitHubWorkflowTemplate;
use ncc\Classes\PhpExtension\Templates\LibraryTemplate;
use ncc\Classes\PhpExtension\Templates\MakefileTemplate;
use ncc\Classes\PhpExtension\Templates\PhpUnitTemplate;
@ -190,25 +191,25 @@
*/
public function applyTemplate(string $template_name): void
{
switch(strtolower($template_name))
switch(ProjectTemplates::tryFrom(strtolower($template_name)))
{
case ProjectTemplates::PHP_CLI->value:
case ProjectTemplates::PHP_CLI:
CliTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_LIBRARY->value:
case ProjectTemplates::PHP_LIBRARY:
LibraryTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_MAKE->value:
case ProjectTemplates::PHP_MAKE:
MakefileTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_UNIT->value:
case ProjectTemplates::PHP_UNIT:
PhpUnitTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_LIBRARY_FULL->value:
case ProjectTemplates::PHP_LIBRARY_FULL:
LibraryTemplate::applyTemplate($this);
MakefileTemplate::applyTemplate($this);
PhpUnitTemplate::applyTemplate($this);
@ -221,7 +222,17 @@
PhpUnitTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_GITHUB_CI:
GitHubWorkflowTemplate::applyTemplate($this);
break;
default:
$suggestion = ProjectTemplates::suggest($template_name);
if($suggestion !== null)
{
throw new NotSupportedException('The given template \'' . $template_name . '\' is not supported, did you mean \'' . $suggestion->value . '\'?');
}
throw new NotSupportedException('The given template \'' . $template_name . '\' is not supported');
}
}