Skip to content

Commit

Permalink
On branch update
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyCTHsu committed Sep 19, 2024
1 parent 4dd912a commit bd2b1ce
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 18 deletions.
9 changes: 9 additions & 0 deletions .github/dependency_filters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
dependencies:
- Gemfile
- Appraisals
- datadog.gemspec
- tasks/appraisal.rake
- .github/workflows/lock-dependency.yml
- lib/datadog/version.rb
- appraisal/**
- gemfiles/**
71 changes: 53 additions & 18 deletions .github/workflows/lock-dependency.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,65 @@
name: Lock Dependency

# TODO: Make this job mandatory
# TODO: Make this on workflow_dispatch

on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to be lock dependency'
required: true
# Testing purpose, to be removed before merge.
# Limitation about `paths` types:
# > https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#git-diff-comparisons
push:
branches:
- tonycthsu/automate-update-gemfiles
branches-ignore:
- master
- release
- '*-stable'
pull_request:
# Run this job when a PR is opened, covering the scenario where branch is ready and pushed before PR is opened.
types:
- opened


# Ensure obsolete job is cancelled if another commit is pushed to the same branch.
# TODO: Improve concurrency between push event and pull_request event
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
# TODO: In order to fully automate this workflow for each PR,
# have a reliable way to precheck job to understand whether it need to be updated
pr:
name: Pull Request attached
runs-on: ubuntu-latest
outputs:
pr_found: ${{ steps.pr.outputs.pr_found }}
pr_base_ref: ${{ steps.pr.outputs.pr.base.ref }}
steps:
# Limitation with pull_request trigger: https://github.com/8BitJonny/gh-get-current-pr/tree/3.0.0/?tab=readme-ov-file#limitations
- uses: 8BitJonny/gh-get-current-pr@3.0.0
id: pr
with:
filterOutClosed: true # Don't trigger on commits with closed PRs, including merges into `master`.

dependency:
name: Depenedency changes
needs: pr
if: ${{ needs.pr.outputs.pr_found == 'true' }}
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.changes.outputs.dependencies }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
# This is the best effort to get the diff comparison.
# The result remains time-sensitive since the `base` is constantly changing and
# the PR cannot be guaranteed to be up-to-date.
#
# Unless enable `Require branches to be up to date before merging` in the repository rule settings
base: ${{ needs.pr.outputs.pr_base_ref }}
filters: .github/dependency_filters.yml

lock:
runs-on: ubuntu-latest
needs: dependency
if: ${{ needs.dependency.outputs.changes == 'true' }}
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -54,39 +93,35 @@ jobs:
BUNDLE_WITHOUT: check
steps:
- uses: actions/checkout@v4
- run: ls -al
- run: |
ruby -v
gem -v
bundler -v
- run: bundle install

# TODO: Migrate away from `appraisal`
- run: bundle exec appraisal generate
- run: bundle exec rake dependency:lock

- uses: actions/upload-artifact@v4
with:
name: lock-dependency-${{ github.run_id }}-${{ matrix.engine.name }}-${{ matrix.engine.version }}
path: gemfiles/${{ matrix.engine.name }}_${{ matrix.engine.version }}*

# TODO: Change token to trigger workflow automation
# > New commit by GITHUB_TOKEN does not trigger workflow automation to prevent infinite loop
commit:
name: Commit changes
needs: lock
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
path: gemfiles
pattern: lock-dependency-${{ github.run_id }}-*
merge-multiple: true

- run: git diff --color

- uses: stefanzweifel/git-auto-commit-action@v5
with:
file_pattern: 'gemfiles/*'
Expand Down
83 changes: 83 additions & 0 deletions .github/workflows/update-gemfiles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Update Gemfiles

# This action cannot be skipped altogether because it is a mandatory status check.
# Instead we conditionally skip it at job level, instead of workflow level.
on:
# Execute on `push` and not `pull_request` because `pull_request`
# always compares if the `paths` have changed compared to the PR base.
# This is an issue because it means that all commits to the branch
# will trigger the gemfile update process, which is unnecessary and expensive.
#
# By executing on `push`, GitHub compares `paths` with the parent commit,
# meaning the gemfile update process will only execute on the exact commit
# that changes any of the `paths`.
#
# Because this process is slow and expensive, and we commit the gemfile changes back
# to the branch, we have an additional filter to only execute this action on branches
# attached to a PR.
#
# We could do the inverse: execute this action on `pull_request`, and additionally check
# if `paths` was changed compared to the parent commit, but this proved more complicated.
push

# Ensure obsolete job is cancelled if another commit is pushed to the same branch.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
check:
name: Update Gemfiles
runs-on: ubuntu-22.04
permissions:
contents: write
pull-requests: write
steps:
# Only execute if there's a PR attached to this branch.
# Because we execute on `push`, we have to double check here if this is part of a PR.
- name: Check if this branch is attached to a Pull Request
uses: 8bitjonny/gh-get-current-pr@2215326c76d51bfa3f2af0a470f32677f6c0cae9 # v2.2.0
id: pr
with:
filterOutClosed: true # Don't trigger on commits with closed PRs, including merges into `master`.
- if: steps.pr.outputs.pr_found == 'true'
uses: actions/checkout@v4
# And also, only execute if files that can affect gemfiles are modified.
- if: steps.pr.outputs.pr_found == 'true'
uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
id: filter
with:
base: ${{ github.ref_name }}
filters: |
gemfile:
# Files that declare the dependency tree
- Gemfile
- Appraisals
- datadog.gemspec
# Files that control gemfile generation
- tasks/appraisal.rake
- .github/workflows/update-gemfiles.yml
# The gem version is present in all lock files
- lib/datadog/version.rb
# In case the generated files were updated manually or in a merge commit
- appraisal/**
- gemfiles/**
- if: steps.pr.outputs.pr_found == 'true' && steps.filter.outputs.gemfile == 'true'
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- if: steps.pr.outputs.pr_found == 'true' && steps.filter.outputs.gemfile == 'true'
name: Ensure gemfiles/*.gemfile.lock match gem definition
run: bundle exec rake appraisal:lock
- if: steps.pr.outputs.pr_found == 'true' && steps.filter.outputs.gemfile == 'true'
name: Add all supported platforms to gemfiles/*.gemfile.lock
run: bundle exec rake appraisal:platform
- if: steps.pr.outputs.pr_found == 'true' && steps.filter.outputs.gemfile == 'true'
name: Remove obsolete gemfiles/*
run: bundle exec rake appraisal:clean
- if: steps.pr.outputs.pr_found == 'true' && steps.filter.outputs.gemfile == 'true'
name: Commit gemfiles changes, if any, back to the branch
uses: stefanzweifel/git-auto-commit-action@3ea6ae190baf489ba007f7c92608f33ce20ef04a # v4.16.0
with:
commit_message: Update gemfiles/*

0 comments on commit bd2b1ce

Please sign in to comment.