Skip to the content.

CI integration

GitHub Actions (bundled composite action)

Lint on every pull request and upload SARIF to GitHub code scanning:

# .github/workflows/easel.yml
name: easel
on: [pull_request]

permissions:
  contents: read
  security-events: write   # required to upload SARIF

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run easel
        uses: lukoplt/easel/action@v0     # or a pinned SHA
        with:
          path: ./src/MyApp          # unpacked pa.yaml folder or a .msapp
          format: sarif
          fail-on: warning
          output: easel.sarif

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: easel.sarif

The action installs pac and easel, runs easel lint, and fails the job when findings reach fail-on. Findings appear inline on the PR via code scanning.

dotnet tool (any CI)

dotnet tool install --global Microsoft.PowerApps.CLI.Tool
dotnet tool install --global EaselCli
export PATH="$PATH:$HOME/.dotnet/tools"

easel lint ./src/MyApp --format sarif -o easel.sarif --fail-on warning

Exit code 1 means findings reached the threshold — the step fails and gates the build.

Diff in a PR

Compare the app on the PR branch against the base branch and post the changelog as a comment. The comment body is easel’s own generated Markdown — no PR title/body is interpolated into any run: step, so there is no injection surface.

# .github/workflows/easel-diff.yml
name: easel diff
on: [pull_request]

permissions:
  contents: read
  pull-requests: write

jobs:
  diff:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout head
        uses: actions/checkout@v4
        with:
          path: head

      - name: Checkout base
        uses: actions/checkout@v4
        with:
          ref: $
          path: base

      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '10.0.x'
      - run: dotnet tool install --global EaselCli
      - run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"

      - name: Generate diff
        run: easel diff base/src/MyApp head/src/MyApp --format markdown -o diff.md

      - name: Comment on PR
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const body = fs.readFileSync('diff.md', 'utf8');
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body,
            });

Adjust base/src/MyApp and head/src/MyApp to your app’s path.