├── .circleci └── config.yml ├── .github └── workflows │ ├── enforce-license-compliance.yml │ └── workflow.yml ├── README.md ├── SECURITY.md ├── azure-pipelines.yml ├── license.txt ├── runMyTests.m ├── source └── quadraticSolver.m └── tests └── SolverTest.m /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | orbs: 3 | matlab: mathworks/matlab@1 4 | codecov: codecov/codecov@4 5 | jobs: 6 | build: 7 | machine: 8 | image: ubuntu-2204:current 9 | steps: 10 | - checkout 11 | - matlab/install 12 | - matlab/run-tests: 13 | source-folder: source 14 | code-coverage-cobertura: coverage.xml 15 | - codecov/upload: 16 | file: coverage.xml 17 | -------------------------------------------------------------------------------- /.github/workflows/enforce-license-compliance.yml: -------------------------------------------------------------------------------- 1 | name: Enforce License Compliance 2 | 3 | on: 4 | pull_request: 5 | branches: [main, master] 6 | 7 | jobs: 8 | enforce-license-compliance: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: 'Enforce License Compliance' 12 | uses: getsentry/action-enforce-license-compliance@57ba820387a1a9315a46115ee276b2968da51f3d # main 13 | with: 14 | fossa_api_key: ${{ secrets.FOSSA_API_KEY }} 15 | -------------------------------------------------------------------------------- /.github/workflows/workflow.yml: -------------------------------------------------------------------------------- 1 | name: Example 2 | on: push 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | - uses: matlab-actions/setup-matlab@v2 9 | - uses: matlab-actions/run-tests@v2 10 | with: 11 | source-folder: source 12 | code-coverage-cobertura: coverage.xml 13 | - uses: codecov/codecov-action@v4 14 | with: 15 | file: coverage.xml 16 | token: ${{ secrets.CODECOV_TOKEN }} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Use MATLAB with [Codecov](https://codecov.io) 2 | 3 | This example shows how to run MATLAB® tests, produce code coverage results, and upload the results to Codecov. The repository includes these files. 4 | 5 | | **File Path** | **Description** | 6 | |--------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| 7 | | `source/quadraticSolver.m` | A function that solves quadratic equations | 8 | | `tests/SolverTest.m` | A class that tests the `quadraticSolver` function | 9 | | `runMyTests.m` | A script that creates a test suite and a test runner that produces code coverage results in Cobertura XML format | 10 | | `azure-pipelines.yml` | A configuration example for [Azure® DevOps](https://marketplace.visualstudio.com/items?itemName=MathWorks.matlab-azure-devops-extension) | 11 | | `.circleci/config.yml` | A configuration example for [CircleCI®](https://circleci.com/orbs/registry/orb/mathworks/matlab) 12 | | `.github/workflows/workflow.yml` | A configuration example for [GitHub® Actions](https://github.com/matlab-actions) 13 | 14 | ## Produce and Publish Coverage Results 15 | Each of these pipeline definitions does four things: 16 | 17 | 1) Install the latest MATLAB release on a Linux®-based build agent. 18 | 2) Run all MATLAB tests in the root of your repository, including its subfolders. 19 | 3) Produce code coverage results in Cobertura XML format for the `source` folder. 20 | 4) Upload the coverage artifact to Codecov. 21 | 22 | ### Azure DevOps 23 | 24 | ```yml 25 | pool: 26 | vmImage: ubuntu-latest 27 | steps: 28 | - task: InstallMATLAB@1 29 | - task: RunMATLABTests@1 30 | inputs: 31 | sourceFolder: source 32 | codeCoverageCobertura: coverage.xml 33 | - script: | 34 | # download Codecov CLI 35 | curl -Os https://cli.codecov.io/latest/linux/codecov 36 | 37 | # integrity check 38 | curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import # One-time step 39 | curl -Os https://cli.codecov.io/latest/linux/codecov 40 | curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM 41 | curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM.sig 42 | gpgv codecov.SHA256SUM.sig codecov.SHA256SUM 43 | 44 | # upload to Codecov 45 | shasum -a 256 -c codecov.SHA256SUM 46 | sudo chmod +x codecov 47 | ./codecov upload-process -t $(CODECOV_TOKEN) 48 | ``` 49 | 50 | ### CircleCI 51 | 52 | ```yml 53 | version: 2.1 54 | orbs: 55 | matlab: mathworks/matlab@1 56 | codecov: codecov/codecov@4 57 | jobs: 58 | build: 59 | machine: 60 | image: ubuntu-2204:current 61 | steps: 62 | - checkout 63 | - matlab/install 64 | - matlab/run-tests: 65 | source-folder: source 66 | code-coverage-cobertura: coverage.xml 67 | - codecov/upload: 68 | file: coverage.xml 69 | ``` 70 | 71 | ### GitHub Actions 72 | 73 | ```yml 74 | name: Example 75 | on: push 76 | jobs: 77 | build: 78 | runs-on: ubuntu-latest 79 | steps: 80 | - uses: actions/checkout@v4 81 | - uses: matlab-actions/setup-matlab@v2 82 | - uses: matlab-actions/run-tests@v2 83 | with: 84 | source-folder: source 85 | code-coverage-cobertura: coverage.xml 86 | - uses: codecov/codecov-action@v4 87 | with: 88 | file: coverage.xml 89 | ``` 90 | 91 | ## Links 92 | - [Community Boards](https://community.codecov.io) 93 | - [Support](https://codecov.io/support) 94 | - [Documentation](https://docs.codecov.io) 95 | - [Continuous Integration with MATLAB and Simulink](https://www.mathworks.com/solutions/continuous-integration.html) 96 | 97 | ## Contact Us 98 | If you have any questions or suggestions, please contact MathWorks® at [continuous-integration@mathworks.com](mailto:continuous-integration@mathworks.com). 99 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Vulnerabilities 2 | 3 | If you believe you have discovered a security vulnerability, please report it to 4 | [security@mathworks.com](mailto:security@mathworks.com). Please see 5 | [MathWorks Vulnerability Disclosure Policy for Security Researchers](https://www.mathworks.com/company/aboutus/policies_statements/vulnerability-disclosure-policy.html) 6 | for additional information. -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | pool: 2 | vmImage: ubuntu-latest 3 | steps: 4 | - task: InstallMATLAB@1 5 | - task: RunMATLABTests@1 6 | inputs: 7 | sourceFolder: source 8 | codeCoverageCobertura: coverage.xml 9 | - script: | 10 | # download Codecov CLI 11 | curl -Os https://cli.codecov.io/latest/linux/codecov 12 | 13 | # integrity check 14 | curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import # One-time step 15 | curl -Os https://cli.codecov.io/latest/linux/codecov 16 | curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM 17 | curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM.sig 18 | gpgv codecov.SHA256SUM.sig codecov.SHA256SUM 19 | 20 | # upload to Codecov 21 | shasum -a 256 -c codecov.SHA256SUM 22 | sudo chmod +x codecov 23 | ./codecov upload-process -t $(CODECOV_TOKEN) 24 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021, The MathWorks, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. In all cases, the software is, and all modifications and derivatives of the 15 | software shall be, licensed to you solely for use in conjunction with 16 | MathWorks products and service offerings. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /runMyTests.m: -------------------------------------------------------------------------------- 1 | % Copyright 2021 The MathWorks, Inc. 2 | 3 | import matlab.unittest.TestRunner 4 | import matlab.unittest.Verbosity 5 | import matlab.unittest.plugins.CodeCoveragePlugin 6 | import matlab.unittest.plugins.codecoverage.CoberturaFormat 7 | 8 | % Add the source folder to the MATLAB search path 9 | addpath('source') 10 | 11 | % Create a test suite 12 | suite = testsuite(pwd,'IncludeSubfolders',true); 13 | 14 | % Create a test runner that displays test run progress at the matlab.unittest.Verbosity.Detailed level 15 | runner = TestRunner.withTextOutput('OutputDetail',Verbosity.Detailed); 16 | 17 | % Create a CodeCoveragePlugin instance and add it to the test runner 18 | sourceFolder = 'source'; 19 | reportFile = 'cobertura.xml'; 20 | reportFormat = CoberturaFormat(reportFile); 21 | p = CodeCoveragePlugin.forFolder(sourceFolder,'IncludingSubfolders', true,'Producing',reportFormat); 22 | runner.addPlugin(p) 23 | 24 | % Run the tests and fail the build if any of the tests fails 25 | results = runner.run(suite); 26 | nfailed = nnz([results.Failed]); 27 | assert(nfailed == 0,[num2str(nfailed) ' test(s) failed.']) -------------------------------------------------------------------------------- /source/quadraticSolver.m: -------------------------------------------------------------------------------- 1 | function roots = quadraticSolver(a,b,c) 2 | % quadraticSolver returns solutions to the 3 | % quadratic equation a*x^2 + b*x + c = 0. 4 | % Copyright 2021 The MathWorks, Inc. 5 | 6 | if ~isa(a,'numeric') || ~isa(b,'numeric') || ~isa(c,'numeric') 7 | error('quadraticSolver:InputMustBeNumeric', ... 8 | 'Coefficients must be numeric.'); 9 | end 10 | 11 | roots(1) = (-b + sqrt(b^2 - 4*a*c)) / (2*a); 12 | roots(2) = (-b - sqrt(b^2 - 4*a*c)) / (2*a); 13 | 14 | end -------------------------------------------------------------------------------- /tests/SolverTest.m: -------------------------------------------------------------------------------- 1 | classdef SolverTest < matlab.unittest.TestCase 2 | % Copyright 2021 The MathWorks, Inc. 3 | methods(Test) 4 | function realSolution(testCase) 5 | actSolution = quadraticSolver(1,-3,2); 6 | expSolution = [2 1]; 7 | testCase.verifyEqual(actSolution,expSolution) 8 | end 9 | function imaginarySolution(testCase) 10 | actSolution = quadraticSolver(1,2,10); 11 | expSolution = [-1+3i -1-3i]; 12 | testCase.verifyEqual(actSolution,expSolution) 13 | end 14 | function nonnumericInput(testCase) 15 | testCase.verifyError(@()quadraticSolver(1,'-3',2), ... 16 | 'quadraticSolver:InputMustBeNumeric') 17 | end 18 | end 19 | end --------------------------------------------------------------------------------