diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..43e6aa12a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,12 @@ +name: CI +on: [push, pull_request, workflow_dispatch] +permissions: { contents: read } +jobs: + snodec: + uses: SNodeC/.github/.github/workflows/verify.yml@v1.0 + secrets: inherit + x-sdk: + needs: snodec + if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }} + permissions: { contents: write } + uses: SNodeC/.github/.github/workflows/publish-dev.yml@v1.0 diff --git a/.snodec/repo.yml b/.snodec/repo.yml new file mode 100644 index 000000000..ad0afe2f6 --- /dev/null +++ b/.snodec/repo.yml @@ -0,0 +1,18 @@ +# Build specifics only; identity lives in SNodeC/.github/catalog.yml. +ci: + profile: cpp + apt: + - libncurses-dev + deps: [] + cmake_options: + - -DCMAKE_BUILD_TYPE=Debug + - -DSNODEC_BUILD_TESTS=ON + - -DSNODEC_BUILD_APPS=ON + ctest_args: + - --output-on-failure + - --parallel + - '8' + ipv6: true + runtime_dirs: true + parallel: 8 + sdk: true diff --git a/tests/policy/ci/CiWorkflowPathsPolicyTest.cpp b/tests/policy/ci/CiWorkflowPathsPolicyTest.cpp index c6e42b257..2f640259c 100644 --- a/tests/policy/ci/CiWorkflowPathsPolicyTest.cpp +++ b/tests/policy/ci/CiWorkflowPathsPolicyTest.cpp @@ -31,7 +31,7 @@ namespace { using Filters = std::map>; using Triggers = std::map; - // Read trigger mappings with inline or block lists; ignore the workflow jobs. + // Read trigger mappings or an inline event list; ignore the workflow jobs. bool matchesTriggers(std::string_view source, const Triggers& expected) { Triggers events; std::istringstream lines{std::string(source)}; @@ -52,6 +52,19 @@ namespace { if (inOn && foundOn) { return false; } + if (content.starts_with("on: [") && content.ends_with(']')) { + if (foundOn) { + return false; + } + foundOn = true; + std::istringstream items(content.substr(5, content.size() - 6)); + std::string item; + while (std::getline(items, item, ',')) { + if (!events.emplace(unquote(trim(item)), Filters{}).second) { + return false; + } + } + } foundOn = foundOn || inOn; event.clear(); filter.clear(); @@ -103,14 +116,18 @@ int main() { return 1; } const std::map workflows = { - {"packages.yml", {{"push", {{"tags", {"v[0-9]*.[0-9]*.[0-9]*"}}}}, - {"repository_dispatch", {{"types", {"package-build"}}}}}}, + {"ci.yml", {{"push", {}}, {"pull_request", {}}, {"workflow_dispatch", {}}}}, + {"packages.yml", {{"push", {{"tags", {"v[0-9]*.[0-9]*.[0-9]*"}}}}, {"repository_dispatch", {{"types", {"package-build"}}}}}}, }; - bool ok = true; + const Triggers verifyEvents = {{"push", {}}, {"pull_request", {}}, {"workflow_dispatch", {}}}; + bool ok = matchesTriggers("on: [push, pull_request, workflow_dispatch]\n", verifyEvents) && + !matchesTriggers("on: [push, push, pull_request, workflow_dispatch]\n", verifyEvents) && + !matchesTriggers("on: [push, pull_request, release]\n", verifyEvents) && + !matchesTriggers("on: [push, pull_request, workflow_dispatch]\non: [push]\n", verifyEvents); for (const auto& [name, triggers] : workflows) { const auto path = root / ".github/workflows" / name; if (!matchesTriggers(source_policy::readSourcePolicyFile(path), triggers)) { - std::cerr << "Unexpected CI triggers in " << path << ": only version-tag package builds and package-build handoffs are allowed\n"; + std::cerr << "Unexpected CI triggers in " << path << ": expected Verify events or version-tag/package-build events\n"; ok = false; } }