All docs

Workflows

The YAML for Daisi Git CI. Triggers, jobs, every step type, and the placeholders a run fills in.

  1. Where the file lives

    A workflow is one YAML document stored with the repository on the server. New Workflow on the repo, or dg workflow create, is how you add it. YAML is how you author it — it is not a path the runner reads out of your working tree. Run now on the site, or dg workflow run, starts it. The dg commands are on Daisi Git.

  2. Top-level fields

    name, on, and jobs are the core. A bare top-level steps: is also accepted and runs as one implicit job. runtime is the container image: minimal (default), dotnet, node, python, or full, and may be set per job. os is linux (default) or windows; runs-on is the alias. dg workflow create file.yml --os windows overrides the file. env is workflow-wide and shows up as {{env.NAME}} and in run steps. vars is non-secret config, usually inherited from repo or org settings, as {{vars.NAME}}. concurrency is a mutual-exclusion group and can cancel an in-progress run in that group.

    name: Build and echo
    on: workflow_dispatch
    runtime: dotnet
    os: linux
    env:
      GREETING: hello
    jobs:
      build:
        steps:
          - name: Say hi
            uses: run
            with:
              run: echo {{env.GREETING}}
  3. Triggers

    on is one event, a list, or a map with filters. push filters on branches. pull_request types are opened, closed, and merged, plus branches. issues types are opened, closed, and reopened. issue_comment fires when a comment is created. pull_request_review fires when a review is submitted or dismissed. create and delete fire when a branch or tag is created or deleted. fork fires when the repository is forked. workflow_dispatch is the manual Run now, from the site or dg workflow run, and takes inputs. branches is a YAML list or a comma-separated string. Scheduled runs are set on the workflow’s schedule settings, not in the on: block.

    on: push
    
    on: [push, pull_request, workflow_dispatch]
    
    on:
      push:
        branches: [main, dev]
      pull_request:
        types: [opened, merged]
        branches: [main]
  4. Manual inputs

    workflow_dispatch inputs are prompted on a manual run and read as {{inputs.NAME}}. type is string, number, boolean, or choice.

    on:
      workflow_dispatch:
        inputs:
          cli_version:
            description: CLI version to release
            type: string
            required: true
            default: "0.2.0"
          channel:
            type: choice
            default: stable
            options: [stable, beta]
  5. Jobs and steps

    Each job has an id and steps. A step picks a type with uses and passes inputs under with. name is an optional label. if is a condition. enabled defaults to true; false skips the step without deleting it. needs orders jobs and is sorted so a cycle is rejected; upstream outputs are available. strategy.matrix fans a job or step out over the product of its dimensions, and each cell sees {{matrix.NAME}}.

    jobs:
      test:
        name: Test
        runtime: dotnet
        strategy:
          matrix:
            os: [ubuntu, windows]
            dotnet: ["8", "10"]
        steps:
          - name: Checkout
            uses: checkout
          - uses: run
            if: push.branch == "main"
            enabled: true
            with:
              run: echo {{matrix.os}} / {{matrix.dotnet}}
    
      publish:
        needs: [test]
        outputs:
          url: "{{steps.deploy.deployUrl}}"
        steps:
          - uses: run
            with:
              run: echo done
  6. if conditions

    A step’s if is KEY OP "VALUE", or a bare KEY when you only need it to be present. Operators are == and != (case-insensitive) and contains (substring).

    if: repo.name == "my-repo"
    if: push.branch != "main"
    if: push.changedPaths contains "src/"
    if: pr.number
  7. Scripts, checkout, issues, HTTP

    uses selects the step. Aliases are in parentheses. run (script, run-script, shell) runs bash on Linux and cmd on Windows. timeout is seconds, max 1800. checkout (clone) puts a repo in the workspace; repo defaults to the current one and also accepts an external git URL. add-comment (comment), set-label (add-label), remove-label, require-review, close-issue, and close-pr (close-pull-request) act on the issue or pull request from the triggering event. http-request (webhook) and send-email (email) call out.

    - uses: run
      with:
        run: dotnet test
        working-directory: src
        timeout: 600
    
    - uses: checkout
      with:
        repo: owner/slug
        branch: main
        path: app
    
    - uses: add-comment
      with: { body: "Thanks for the PR!" }
    - uses: set-label
      with: { label: needs-review }
    - uses: remove-label
      with: { label: stale }
    - uses: require-review
      with: { approvals: "2" }
    - uses: close-issue
    - uses: close-pr
    
    - uses: http-request
      with:
        url: https://example.com/hook
        method: POST
        content-type: application/json
        headers: { Authorization: "Bearer {{secrets.TOKEN}}" }
        body: '{"ref":"{{push.branch}}"}'
    
    - uses: send-email
      with:
        to: team@example.com
        subject: Build {{repo.name}}
        body: Done.
  8. Build, publish, deploy

    deploy-azure-webapp (deploy-azure, azure-deploy) deploys a folder to an Azure App Service name. auth-mode is basic (default) or oidc. deploy-daisi-srv (deploy-srv, daisi-srv-deploy) zip-deploys a folder to a Srv site; the token secret name defaults to DAISI_SRV_TOKEN. acr-build (docker-build) builds an image in Azure Container Registry. nuget-push (dotnet-nuget-push) pushes a package. create-release (github-release, gh-release) tags a release and can attach files.

    - uses: deploy-azure-webapp
      with:
        app-name: my-web-app
        path: publish
        auth-mode: basic
        username-secret: AZ_FTP_USER
        password-secret: AZ_FTP_PASS
    
    - uses: deploy-daisi-srv
      with:
        site: marketing
        token-secret: DAISI_SRV_TOKEN
        path: publish
        stage: "true"
        notes: "{{push.commit}}"
    
    - uses: acr-build
      with:
        registry: myregistry
        image: app:latest,app:1.0
        dockerfile: Dockerfile
        context: .
        platform: linux
        build-args: ENV=prod,VER=1.0
    
    - uses: nuget-push
      with:
        package: "**/*.nupkg"
        api-key-secret: NUGET_KEY
        source: https://api.nuget.org/v3/index.json
        skip-duplicate: "true"
    
    - uses: create-release
      with:
        tag: v1.2.0
        name: Release 1.2.0
        body: Changelog here...
        prerelease: "true"
        files: dist/app.zip,dist/notes.txt
  9. Artifacts, waits, and agents

    upload-artifact and download-artifact move a file or directory between jobs. condition (if) is a branch marker. wait takes days, hours, or minutes. wait-for-approval (approval, manual-approval) pauses for a person; an empty approvers list is anyone with write access. dispatch-workflow (trigger-workflow) starts another workflow and can wait on it. run-minion (minion) runs a Daisinet agent and needs a .NET-capable runtime. timeout max is 1800 seconds.

    - uses: upload-artifact
      with: { name: binaries, path: dist }
    - uses: download-artifact
      with: { name: binaries, path: ./in }
    
    - uses: wait
      with: { minutes: 5 }
    
    - uses: wait-for-approval
      with:
        environment: prod
        approvers: ""
        message: Approve production deploy?
    
    - uses: dispatch-workflow
      with:
        repo: owner/slug
        workflow: deploy
        inputs: env=prod,tag={{push.tag}}
        wait: "true"
    
    - uses: run-minion
      with:
        instructions: Summarize the changed files.
        model: "Qwen 3.5"
        max-iterations: "20"
        json: "true"
        timeout: 1500
  10. Placeholders

    Any string, including with inputs, may contain {{ ... }}. Repository: {{repo.name}}, {{repo.slug}}, {{repo.ownerName}}, {{repo.defaultBranch}}, {{repo.visibility}}. Who ran it: {{actor.id}}, {{actor.name}}. Push: {{push.branch}}, {{push.tag}}, {{push.commit}}, {{push.changedPaths}}. Pull request: {{pr.number}}, {{pr.title}}, {{pr.headSha}}, {{pr.targetBranch}}. Issue: {{issue.number}}, {{issue.label}}. Also {{inputs.NAME}}, {{env.NAME}}, {{vars.NAME}}, {{secrets.NAME}} (never written to logs), {{matrix.NAME}}, {{steps.ID.output}} plus .exitCode, .status, .response, .deployUrl, and .success, and {{needs.JOB.outputs.NAME}}. In a run step, {{secrets.NAME}} is also the environment variable SECRET_NAME, and {{env.NAME}} is NAME. A step does not inherit the runner’s environment. Only an allowlist is passed through — PATH, HOME, TMPDIR, DOTNET_*, TLS trust paths — plus what the workflow declares in env and secrets. If a step needs any other variable, declare it.

  11. Examples

    Comment on an opened pull request and label it. A manual release checks out, packs, and creates a release. A Windows worker uses cmd.exe for run; register it with dg workflow create windows-ci.yml --os windows when the file omits os.

    name: Greet PRs
    on:
      pull_request:
        types: [opened]
    jobs:
      greet:
        steps:
          - uses: add-comment
            with:
              body: "Thanks @{{actor.name}} — a reviewer will take a look."
          - uses: set-label
            with: { label: needs-review }
    
    name: Release
    on:
      workflow_dispatch:
        inputs:
          version: { type: string, required: true }
    runtime: full
    jobs:
      release:
        steps:
          - uses: checkout
          - name: build
            uses: run
            with:
              run: dotnet pack -c Release -o dist /p:Version={{inputs.version}}
          - uses: create-release
            with:
              tag: "v{{inputs.version}}"
              files: dist/*.nupkg
    
    name: Windows CI
    on: workflow_dispatch
    os: windows
    runtime: dotnet
    jobs:
      build:
        steps:
          - uses: checkout
          - uses: run
            with:
              run: |
                echo %OS%
                dotnet build -c Release

Reviewed October 2026.