# GitHub Workflows GitHub workflows can run one or more tasks when triggered by specific events, e.g. pushing commits, raising issues or pull requests. An event triggers a configured workflow which contains one or more jobs. A job contains a one or more steps which defines actions to run. [:fontawesome-solid-book-open: Practicalli GitHub Workflows](https://practical.li/engineering-playbook/continuous-integration/github/workflows/practicalli/){target=_blank .md-button} [:globe_with_meridians: Understanding GitHub Actions](https://docs.github.com/en/actions/about-github-actions/understanding-github-actions){target=_blank .md-button} ## Anatomy of a workflow | Term | Description | |----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Event | [Triggers a workflow](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows), e.g. Create pull request, push commit, etc. | | Workflow | Top level configuration containing one or more jobs, [triggered by a specific event](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows) | | Job | Set of steps executed in the same runner, multiple jobs execute in parallel within their own instance of a runner | | Step | Individual task that runs commands (actions), sharing data with other steps | | Action | Standalone commands defined within a step, custom commands or GitHub community | | Runner | A GitHub Actions server, listening for available jobs | ## Example GitHub Action `.github/workflows/workflow-name.yaml` is a file that contains the workflow definition. > NOTE: Practicalli recommends including additional configuration in `.github/config/` files where required, rather than the root directory of a project [Setup Java](https://github.com/actions/setup-java){target=_blank} adds an OpenJDK distribution, i.e. Eclipse Temurin, at a specified version. [Setup Clojure](https://github.com/DeLaGuardo/setup-clojure){target=_blank} provides Clojure via Clojure CLI or Leiningen. [Cache](https://github.com/actions/cache){target=_blank} is used to cache Clojure and Java libraries * The example workflow runs on Ubuntu. * The project code is checked out from the Git repository. * Java and Clojure run-times are added to the environment * Unit tests are run using the `:test/run` alias (this alias should run Kaocha or similar test runner) * Source code format and idioms are checked with cljstyle and clj-kondo * The Clojure project is packaged into an Uberjar for deployment !!! EXAMPLE "Example GitHub workflow for Clojure CLI project" ```yaml name: Test and Package project on: pull_request: push: branches: - main jobs: clojure: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Cache Clojure Dependencies uses: actions/cache@v3 with: path: - ~/.m2 - ~/.gitlibs key: cache-${{ hashFiles('**/deps.edn') }} restore-keys: clojure-deps- - name: Prepare java uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '21' - name: Install clojure tools uses: DeLaGuardo/setup-clojure@9.5 with: cli: 1.11.1.1165 # Clojure CLI based on tools.deps cljstyle: 0.15.0 # cljstyle clj-kondo: 2022.10.05 # Clj-kondo - name: Run Unit tests run: clojure -X:test/run - name: "Lint with clj-kondo" run: clj-kondo --lint deps.edn src resources test --config .clj-kondo/config-ci.edn - name: "Check Clojure Style" run: cljstyle check --report - name: Package Clojure project run: clojure -X:project/uberjar ```