Embedded Software

Embedded Software

Automating Ansys SCADE Suite workflows with GitHub Actions

    • SolutionSolution
      Participant



      Continuous Integration (CI) and Continuous Deployment (CD) are critical in modern software development. In a previous article, we covered ways of setting up CI/CD pipelines with Ansys SCADE.

      Today, we will dive into the GitHub flavor of this process, using our open-source Ansys SCADE Actions for GitHub. We will set up and run a GitHub Actions pipeline on the Cruise Control example model provided with the SCADE Suite product, using a self-hosted runner to perform automated actions.

      Prerequisites

      Before setting up the GitHub workflow, ensure that you have:

      • A GitHub repository containing a SCADE Suite model
      • Basic knowledge of GitHub Actions
      • A self-hosted runner with SCADE Suite installed (this will be used to launch SCADE in batch mode to perform automatic actions on the model).

      Setting up the self-hosted runner

      Ansys SCADE requires a self-hosted runner so that the GitHub Actions pipeline can run automated actions by invoking SCADE in batch mode.

      Follow these steps to set up your runner:

      • Navigate to your GitHub repository and go to Settings > Actions > Runners.
      • Select New self-hosted runner and choose your operating system.
      • Follow the provided instructions to install and configure a Windows runner.
      • Ensure that SCADE Suite is installed and accessible from the runner environment.

      Creating a single self-hosted runner is enough to get started. As you scale up your SCADE CI/CD activities and the volume of jobs increases, you may want to create additional runners to spread the workload.

      SCADE Suite GitHub Actions workflow

      We will now create a GitHub Actions workflow, stored under .github/workflows/scade-ci.yml that automates the process of checking, analyzing, and testing a SCADE model.

      Our workflow will perform four sequential tasks on our model. Each of these tasks launches SCADE in batch mode on our model and produces a report that is archived on the workflow run for later reference. Here is the sequence of actions:

      • scade-check: validate the integrity of the SCADE model.
      • scade-metrics: compute model complexity and quality metrics.
      • test-execute: run automated model tests.
      • suite-report: generate human-readable documentation detailing the model’s architecture and structure, down to individual operator inputs and outputs.

      Below is a screenshot that shows a successful run of this workflow on the CruiseControl example model provided with SCADE Suite. Notice the artifacts attached to the workflow in the bottom half of the image:



      And here is the complete YAML file describing the workflow:

      name: ci-scade-actions
      
      on: 
        pull_request: 
        push: 
          tags: 
            - "*"
          branches: 
            - main
        workflow_dispatch: 
      
      jobs:
        scade-check:
          name: "Check SCADE Suite Model"
          outputs:
            scade-directory: ${{ steps.get-scade-dir.outputs.scade-directory}}
          runs-on: [self-hosted, 'SCADE']
          strategy:
            matrix:
              os: [windows-latest]
              scade-version: ['25.1']
            fail-fast: false
      
          steps:
            - name: "Clone Project"
              uses: actions/checkout@v4
            - name: "Get SCADE Installation Directory"
              uses: ansys/scade-actions/get-scade-dir@v2
              id: get-scade-dir
              with:
                scade-version: "25.1"
            - name: "Check Model"
              uses: ansys/scade-actions/suite-check@v2
              id: suite-check
              with:
                scade-dir: ${{steps.get-scade-dir.outputs.scade-directory}}
                project: "CruiseControl/CruiseControl/CruiseControl.etp"
                configuration: "KCG"
            - name: "Upload Checker report artifacts"
              uses: actions/upload-artifact@v4
              with:
                name: "scade-suite-check-report"
                path: "${{ steps.suite-check.outputs.report}}"
                retention-days: 7
                if-no-files-found: error
      
        scade-metrics:
          name: "Compute Metrics"
          runs-on: [self-hosted, 'SCADE']
          outputs:
            scade-directory: ${{ needs.scade-check.outputs.scade-directory}}
          strategy:
            matrix:
              os: [windows-latest]
              scade-version: ['25.1']
            fail-fast: false
          needs: [scade-check]
      
          steps:
            - name: "Compute Metrics"
              uses: ansys/scade-actions/suite-metrics@v2
              id: suite-metrics
              with:
                scade-dir: ${{needs.scade-check.outputs.scade-directory}}
                configuration: "MetricRule"
                project: "CruiseControl/CruiseControl/CruiseControl.etp"
            - name: "Upload Checker report artifacts"
              uses: actions/upload-artifact@v4
              with:
                name: "metrics"
                path: "${{ steps.suite-metrics.outputs.report}}"
                retention-days: 7
                if-no-files-found: error
      
        test-execute:
          name: "Execute Tests"
          runs-on: [self-hosted, 'SCADE']
          outputs:
            scade-directory: ${{ needs.scade-metrics.outputs.scade-directory}}
          strategy:
            matrix:
              os: [windows-latest]
              scade-version: ['25.1']
            fail-fast: false
          needs: [scade-metrics]
      
          steps:
            - name: "Execute Tests"
              uses: ansys/scade-actions/test-execute@v2
              with:
                scade-dir: ${{needs.scade-metrics.outputs.scade-directory}}
                configuration: "Test"
                test-project: "CruiseControl/CruiseControl_Test/CruiseControl_Test.etp"
                results-project: "CruiseControl/CruiseControl_Result/CruiseControl_Result.etp"
                junit-report: "junit-reports/Model.xml"
            - name: "Upload JUnit report to artifacts"
              uses: actions/upload-artifact@v4
              with:
                name: "junit-report"
                path: "junit-reports\\Model.xml"
                retention-days: 7
                if-no-files-found: error
      
        suite-report:
            name: "Create Report"
            runs-on: [self-hosted, 'SCADE']
            strategy:
              matrix:
                os: [windows-latest]
                scade-version: ['25.1']
              fail-fast: false
            needs: [test-execute]
      
        steps:
          - name: "Create Report"
            uses: ansys/scade-actions/suite-report@v2
            id: suite-report
            with:
              scade-dir: ${{ needs.test-execute.outputs.scade-directory }}
              project: "CruiseControl/CruiseControl/CruiseControl.etp"
              configuration: "RTF"
          - name: "Upload the document to artifacts"
            uses: actions/upload-artifact@v4
            with:
              name: "scade-suite-report"
              path: "${{ steps.suite-report.outputs.report }}"
              retention-days: 7
              if-no-files-found: error
      

      Let’s break down the contents of this file.

      First, we define a name for our workflow in the name: section. We’ll simply call it ci-scade-actions.

      Next, we define what triggers our workflow in the on: section. We want it to run on:

      • Pull Requests: ensures changes are validated before merging.
      • Push Events: any push to the main branch or to a tag.
      • Manual triggers: Through workflow_dispatch. This allows manual triggering via the GitHub web interface, API or CLI (useful for testing).

      Finally, we get the main part: listing the jobs that compose the workflow and how they chain together (jobs: section). Each job in the sequence depends on the previous one (needs: section). This means it won’t run unless the previous job is finished and successful.

      Below is some detail on the steps performed by each job:

      • scade-check:
        • Clone the repository onto the runner machine.
        • Determine the SCADE installation directory (get-scade-dir).
        • Verify semantic correctness of the SCADE model (suite-check on the main operator, CruiseControl.etp).
        • Upload validation report for archival.
      • scade-metrics:
        • Compute metrics using configuration “MetricRule”, defined inside the model.
        • Upload the generated metrics report for archival.
      • test-execute:
        • Execute tests (test-execute).
        • Store results in JUnit XML format.
        • Upload test results for archival.
      • suite-report:
        • Create a model documentation report using the “RTF” configuration, defined inside the model.
        • Upload the report as an artifact for archival.

      Conclusion

      In this article, we used Ansys SCADE Actions for GitHub to automate the verification, testing, and reporting of a SCADE Suite model in a CI/CD pipeline. Such pipelines ensure that safety-critical software is rigorously validated with every code change, improving development efficiency and reliability.

      Ready to get started on your own models? Visit the Ansys SCADE Actions documentation.

      About the author



      Ludovic Oddos (LinkedIn) is a Lead Product Specialist at Ansys. He has been supporting SCADE field engagements, in many industries, for more than 15 years. He has deep expertise in embedded software and its integration into various target environments.