From ed8678c723069eb6651e3c9aaa656eacb7f7b189 Mon Sep 17 00:00:00 2001 From: Alexander Artemenko Date: Sat, 27 Jan 2024 22:56:29 +0300 Subject: [PATCH] Run tests on different lisp implementations. --- .github/workflows/ci.yml | 96 ++++++++++++++++++++++++++++++++++++++ .github/workflows/docs.yml | 23 ++++++++- src/jobs/job.lisp | 7 ++- src/steps/step.lisp | 17 +++++++ src/vars.lisp | 5 +- src/workflow.lisp | 53 +++++++++++++-------- 6 files changed, 176 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3f4788..048f2f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,8 @@ "env": { "OS": "ubuntu-latest", "QUICKLISP_DIST": "quicklisp", + "LISP": "sbcl-bin", + "QUICKLISP_DIST": "quicklisp", "LISP": "sbcl-bin" }, "steps": [ @@ -60,6 +62,37 @@ }, "if": "steps.cache.outputs.cache-hit != 'true'" }, + { + "name": "Checkout Code", + "uses": "actions/checkout@v3" + }, + { + "name": "Setup Common Lisp Environment", + "uses": "40ants/setup-lisp@v2", + "with": { + "asdf-system": "40ants-ci" + } + }, + { + "name": "Change dist to Ultralisp", + "run": "echo 'dist ultralisp http://dist.ultralisp.org' > qlfile", + "shell": "bash" + }, + { + "name": "Update Qlot", + "run": "qlot update --no-deps", + "shell": "bash" + }, + { + "name": "Install SBLint wrapper", + "run": "qlot exec ros install 40ants-linter", + "shell": "bash" + }, + { + "name": "Run Linter", + "run": "qlot exec 40ants-linter --system \"40ants-ci, 40ants-ci-tests\" --imports", + "shell": "bash" + }, { "name": "Change dist to Ultralisp", "run": "echo 'dist ultralisp http://dist.ultralisp.org' > qlfile", @@ -87,6 +120,8 @@ "env": { "OS": "ubuntu-latest", "QUICKLISP_DIST": "quicklisp", + "LISP": "sbcl-bin", + "QUICKLISP_DIST": "quicklisp", "LISP": "sbcl-bin" }, "steps": [ @@ -128,6 +163,37 @@ }, "if": "steps.cache.outputs.cache-hit != 'true'" }, + { + "name": "Checkout Code", + "uses": "actions/checkout@v3" + }, + { + "name": "Setup Common Lisp Environment", + "uses": "40ants/setup-lisp@v2", + "with": { + "asdf-system": "40ants-ci" + } + }, + { + "name": "Change dist to Ultralisp", + "run": "echo 'dist ultralisp http://dist.ultralisp.org' > qlfile", + "shell": "bash" + }, + { + "name": "Update Qlot", + "run": "qlot update || qlot update", + "shell": "bash" + }, + { + "name": "Install LISP-CRITIC wrapper", + "run": "qlot exec ros install 40ants-critic", + "shell": "bash" + }, + { + "name": "Run Critic for \"40ants-ci\" system", + "run": "qlot exec lisp-critic --ignore function-too-long 40ants-ci", + "shell": "bash" + }, { "name": "Change dist to Ultralisp", "run": "echo 'dist ultralisp http://dist.ultralisp.org' > qlfile", @@ -162,6 +228,14 @@ "quicklisp", "ultralisp" ], + "lisp": [ + "sbcl-bin", + "ccl-bin/1.12.1" + ], + "quicklisp": [ + "quicklisp", + "ultralisp" + ], "lisp": [ "sbcl-bin", "ccl-bin/1.12.1" @@ -172,6 +246,8 @@ "env": { "OS": "${{ matrix.os }}", "QUICKLISP_DIST": "${{ matrix.quicklisp }}", + "LISP": "${{ matrix.lisp }}", + "QUICKLISP_DIST": "${{ matrix.quicklisp }}", "LISP": "${{ matrix.lisp }}" }, "steps": [ @@ -214,6 +290,26 @@ }, "if": "steps.cache.outputs.cache-hit != 'true'" }, + { + "name": "Checkout Code", + "uses": "actions/checkout@v3" + }, + { + "name": "Setup Common Lisp Environment", + "uses": "40ants/setup-lisp@v2", + "with": { + "asdf-system": "40ants-ci", + "qlfile-template": "{% ifequal quicklisp_dist \"ultralisp\" %}\ndist ultralisp http://dist.ultralisp.org\n{% endifequal %}" + } + }, + { + "name": "Run Tests", + "uses": "40ants/run-tests@v2", + "with": { + "asdf-system": "40ants-ci", + "coveralls-token": "\n${{ matrix.lisp == 'sbcl-bin' &&\n matrix.os == 'ubuntu-latest' &&\n matrix.quicklisp == 'ultralisp' &&\n secrets.github_token }}" + } + }, { "name": "Run Tests", "uses": "40ants/run-tests@v2", diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index dfb9fbe..aab30ef 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -19,6 +19,8 @@ "env": { "OS": "ubuntu-latest", "QUICKLISP_DIST": "quicklisp", + "LISP": "sbcl-bin", + "QUICKLISP_DIST": "quicklisp", "LISP": "sbcl-bin" }, "steps": [ @@ -60,6 +62,25 @@ }, "if": "steps.cache.outputs.cache-hit != 'true'" }, + { + "name": "Checkout Code", + "uses": "actions/checkout@v3" + }, + { + "name": "Setup Common Lisp Environment", + "uses": "40ants/setup-lisp@v2", + "with": { + "asdf-system": "40ants-ci" + } + }, + { + "name": "Build Docs", + "uses": "40ants/build-docs@v1", + "with": { + "asdf-system": "40ants-ci", + "error-on-warnings": true + } + }, { "name": "Build Docs", "uses": "40ants/build-docs@v1", @@ -71,4 +92,4 @@ ] } } -} +} \ No newline at end of file diff --git a/src/jobs/job.lisp b/src/jobs/job.lisp index d94b28e..7d882b7 100644 --- a/src/jobs/job.lisp +++ b/src/jobs/job.lisp @@ -3,6 +3,8 @@ (:import-from #:40ants-ci/utils #:ensure-list-of-plists) (:import-from #:40ants-ci/github) + (:import-from #:40ants-ci/steps/step + #:ensure-step) (:export #:job #:use-matrix-p @@ -40,7 +42,10 @@ (unless (slot-boundp job 'name) (setf (slot-value job 'name) (string-downcase - (class-name (class-of job)))))) + (class-name (class-of job))) + (slot-value job 'steps) + (mapcar #'ensure-step + (steps job))))) (defmethod os :around ((job job)) (uiop:ensure-list diff --git a/src/steps/step.lisp b/src/steps/step.lisp index 2967f49..d761de1 100644 --- a/src/steps/step.lisp +++ b/src/steps/step.lisp @@ -59,3 +59,20 @@ (when (step-if step) `(("if" . ,(step-if step)))))) + + +(defun ensure-step (step-or-step-definition) + (check-type step-or-step-definition (or step list)) + (etypecase step-or-step-definition + (step step-or-step-definition) + (list + (let ((head (car step-or-step-definition)) + (args (cdr step-or-step-definition))) + + (unless (symbolp head) + (error "~A is not a correct step definition." + step-or-step-definition)) + + (if (fboundp head) + (apply head args) + (apply #'make-instance head args)))))) diff --git a/src/vars.lisp b/src/vars.lisp index 6192066..2548f72 100644 --- a/src/vars.lisp +++ b/src/vars.lisp @@ -11,6 +11,5 @@ "When workflow is generated for ASDF system, this variable will contain a primary ASDF system.") -(defvar *use-cache*) -(setf (documentation '*use-cache* 'variable) - "Workflow will set this variable when preparing the data or YAML generation.") +(defvar *use-cache* nil + "Workflow will set this variable when preparing the data or YAML generation.") diff --git a/src/workflow.lisp b/src/workflow.lisp index 369d089..cc6f12a 100644 --- a/src/workflow.lisp +++ b/src/workflow.lisp @@ -2,6 +2,7 @@ (:use #:cl) (:import-from #:40ants-ci/github #:*current-system*) + (:import-from #:40ants-ci/jobs/job) (:import-from #:40ants-ci/utils #:ensure-primary-system) (:import-from #:40ants-ci/vars) @@ -104,20 +105,24 @@ on-pull-request cache jobs) - `(progn - (defclass ,name (workflow) - ()) - (let* ((jobs (mapcar #'make-job ',jobs)) - (workflow (make-instance ',name - :name ',name - :jobs jobs - :on-push-to ',(uiop:ensure-list on-push-to) - :by-cron ',(uiop:ensure-list by-cron) - :on-pull-request ,on-pull-request - :cache ,cache))) - (register-workflow workflow) - (on-workflow-redefinition workflow) - workflow))) + (let ((make-func-name (intern (format nil "MAKE-~A-WORKFLOW" + name)))) + `(with-current-system () + (defclass ,name (workflow) + ()) + (defun ,make-func-name () + (let ((jobs (mapcar #'make-job ',jobs))) + (make-instance ',name + :name ',name + :jobs jobs + :on-push-to ',(uiop:ensure-list on-push-to) + :by-cron ',(uiop:ensure-list by-cron) + :on-pull-request ,on-pull-request + :cache ,cache))) + (let* ((workflow (,make-func-name) )) + (register-workflow workflow) + (on-workflow-redefinition workflow) + workflow)))) (defgeneric make-triggers (workflow) @@ -207,12 +212,20 @@ to the primary system with same package name as a package where defworkflow is used.") (:method ((workflow workflow)) - (let* ((system-name (string-downcase - (package-name *package*))) - (*current-system* - (asdf:find-system - (asdf:primary-system-name system-name))) - (system-path (40ants-ci/utils:make-github-workflows-path *current-system*)) + (let* ((system-path (40ants-ci/utils:make-github-workflows-path *current-system*)) (workflow-path (make-workflow-path system-path workflow))) (40ants-ci/github:generate workflow workflow-path)))) + + +(defun call-with-current-system (thunk) + (let* ((system-name (string-downcase + (package-name *package*))) + (*current-system* + (asdf:find-system + (asdf:primary-system-name system-name)))) + (funcall thunk))) + + +(defmacro with-current-system (() &body body) + `(call-with-current-system (lambda () ,@body)))