# GitHub Actions Best Practices - Author: Thang Bui Quang - These are some common use cases and best practices of GH Actions that I usually do in my currrent job. ### 1. Conditional jobs run even if some are skipped. ```yaml= jobs: job1: # Run job2: # Skipped report: name: Report Status Check needs: [job1, job2] if: always() ``` ### 2. Conditional jobs based on changed files in PR or latest commit. ```yaml= jobs: check: name: Check files changed outputs: run_job1: ${{ steps.changes.outputs.job1 }} run_job2: ${{ steps.changes.outputs.job2 }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 2 - id: changes uses: dorny/paths-filter@v3 with: filters: | job1: - "path_job1_folder/**" job2: - "path_job2_folder/**" job1: needs: check if: needs.check.outputs.run_job1 == 'true' job2: needs: check if: needs.check.outputs.run_job2 == 'true' ``` ### 3. Delete workflow history ```bash= # Install jq, gh on ubuntu/debian sudo apt-get install jq sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ && sudo apt update \ && sudo apt install gh -y # Install jq, gh on MacOS brew install jq brew install gh ``` ```bash= # Login gh auth login ``` ```bash= export DISPLAY_WORKFLOW_NAME='Build Docker Image' gh run list \ --limit 500 \ --workflow $DISPLAY_WORKFLOW_NAME \ --json databaseId | \ jq -r '.[] | .databaseId | @sh' | \ xargs -I{} gh run delete "{}" ``` ### 4. Composite Actions Comment On PR > Usage: > ```yaml > - name: Report Status > uses: comment-on-pr-path-repo@main > with: > message: | > ## CI Report > > | Service | Status Check | Time | > | ------- | ------------------------ | ----- | > | Job 1 | ${{ needs.job1.result }} | | > > > [!NOTE] > > Some notes > if: always() > ``` ```yaml= name: Comment Pull Request inputs: message: description: 'Comment Body' default: 'No message provided' required: true github-token: description: 'GitHub Token' required: false default: ${{ github.token }} runs: using: "composite" steps: - name: Check if Pull Request shell: bash run: | if [ -z "$GITHUB_HEAD_REF" ]; then echo "This is not a pull request. Exiting..." exit 1 fi - name: Comment on Pull Request uses: actions/github-script@v7 with: github-token: ${{ inputs.github-token }} script: | const commentBody = ` ${{ inputs.message }} `; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: commentBody }); ```