Browse Source

build(ci): Trigger getsentry backend tests on deps change (#23642)

This will trigger getsentry backend test when `requirements*.txt`
changes. This functions similarly to the getsentry javascript test.

The failed check will show you a message w/ instructions on how to proceed:
![image](https://user-images.githubusercontent.com/79684/107104287-c96d2380-67d5-11eb-83a1-3a21a90a0adf.png)
Billy Vong 4 years ago
parent
commit
1f0daad8eb

+ 2 - 0
.eslintignore

@@ -4,3 +4,5 @@
 **/tests/**/lang/javascript/example-project/**/*
 /examples/
 /scripts/
+!.github
+!.github/workflows/scripts/*

+ 5 - 1
.github/file-filters.yml

@@ -29,13 +29,17 @@ frontend_components_modified_lintable:
 backend_lintable: &backend_lintable
   - '**/*.py'
 
+# Currently used in `getsentry-dispatch.yml` to dispatch backend tests on getsentry
+backend_dependencies: &backend_dependencies
+  - 'requirements-*.txt'
+
 backend: &backend
+  - *backend_dependencies
   - *backend_lintable
   - '.pre-commit-config.yaml'
   - '**/*.sh'
   - '**/*.pysnap'
   - 'src/sentry/!(static)/**'
-  - 'requirements-*.txt'
   - 'migrations_lockfile.txt'
   - '.python-version'
   - '.github/workflows/!(js-*)'

+ 43 - 0
.github/workflows/getsentry-dispatch.yml

@@ -0,0 +1,43 @@
+# Dispatch a request to getsentry to run getsentry test suites
+name: getsentry dispatcher
+
+on:
+  # XXX: We are using `pull_request_target` instead of `pull_request` because we want
+  # this to run on forks.  It allows forks to access secrets safely by
+  # only running workflows from the main branch. Prefer to use `pull_request` when possible.
+  #
+  # See https://github.com/getsentry/sentry/pull/21600 for more details
+  pull_request_target:
+
+jobs:
+  dispatch:
+    name: getsentry dispatch
+    runs-on: ubuntu-16.04
+    steps:
+      # Need to checkout just for `github/file-filters.yml`
+      - uses: actions/checkout@v2
+
+      - name: Check for file changes
+        uses: getsentry/paths-filter@v2
+        id: changes
+        with:
+          token: ${{ github.token }}
+          filters: .github/file-filters.yml
+
+      - name: getsentry token
+        uses: getsentry/action-github-app-token@v1
+        id: getsentry
+        with:
+          app_id: ${{ secrets.SENTRY_INTERNAL_APP_ID }}
+          private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
+
+      - name: Dispatch getsentry tests
+        uses: actions/github-script@v3
+        with:
+          github-token: ${{ steps.getsentry.outputs.token }}
+          script: |
+            require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/scripts/getsentry-dispatch`).dispatch({
+              github,
+              context,
+              fileChanges: ${{ toJson(steps.changes.outputs) }}
+            });

+ 0 - 62
.github/workflows/js-getsentry-dispatch.yml

@@ -1,62 +0,0 @@
-# If frontend files change, dispatch a request to getsentry to run its javascript test suites
-name: getsentry dispatcher
-
-on:
-  # XXX: We are using `pull_request_target` instead of `pull_request` because we want
-  # this to run on forks.  It allows forks to access secrets safely by
-  # only running workflows from the main branch. Prefer to use `pull_request` when possible.
-  #
-  # See https://github.com/getsentry/sentry/pull/21600 for more details
-  pull_request_target:
-
-jobs:
-  frontend:
-    name: frontend dispatch
-    runs-on: ubuntu-16.04
-    steps:
-      # Need to checkout just for `github/file-filters.yml`
-      - uses: actions/checkout@v2
-
-      - name: Check for frontend file changes
-        uses: getsentry/paths-filter@v2
-        id: changes
-        with:
-          token: ${{ github.token }}
-          filters: .github/file-filters.yml
-
-      - name: getsentry token
-        uses: getsentry/action-github-app-token@v1
-        id: getsentry
-        with:
-          app_id: ${{ secrets.SENTRY_INTERNAL_APP_ID }}
-          private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
-
-      - name: Dispatch getsentry frontend tests
-        uses: actions/github-script@v3
-        with:
-          github-token: ${{ steps.getsentry.outputs.token }}
-          script: |
-            // Check for getsentry PR dependency
-            const body = context.payload.pull_request.body;
-
-            // Logs convert the full PR URL into a shortened link, but we need to match against the full URL
-            const matches = body && body.match(/requires.*getsentry\/getsentry\/pull\/(\d+)/im);
-            const pr = matches && await github.pulls.get({
-              owner: 'getsentry',
-              repo: 'getsentry',
-              pull_number: matches[1],
-            });
-            const branch = pr ? pr.data.head.ref : '';
-
-            github.actions.createWorkflowDispatch({
-              owner: 'getsentry',
-              repo: 'getsentry',
-              workflow_id: 'js-build-and-lint.yml',
-              ref: 'master',
-              inputs: {
-                pull_request: matches && matches[1] || '',
-                branch,
-                skip: "${{ steps.changes.outputs.frontend != 'true' }}",
-                'sentry-sha': '${{ github.event.pull_request.head.sha }}',
-              }
-            })

+ 43 - 0
.github/workflows/scripts/getsentry-dispatch.js

@@ -0,0 +1,43 @@
+/* eslint-env node */
+
+/**
+ * List of workflows to dispatch to `getsentry`
+ *
+ * `pathFilterName` refers to the path filters in `.github/file-filters.yml` (`getsentry/paths-filter` action)
+ *
+ * TODO(billy): Refactor workflow files to be an enum so that we can integration test them. Otherwise if they are
+ *              deleted/renamed in `getsentry`, this will fail
+ */
+const DISPATCHES = [
+  {
+    workflow: 'js-build-and-lint.yml',
+    pathFilterName: 'frontend',
+  },
+  {
+    workflow: 'backend-test.yml',
+    pathFilterName: 'backend_dependencies',
+  },
+];
+
+module.exports = {
+  dispatch: async ({github, context, fileChanges}) => {
+    const shouldSkip = {
+      frontend: fileChanges.frontend !== 'true',
+      backend_dependencies: fileChanges.backend_dependencies !== 'true',
+    };
+
+    DISPATCHES.forEach(({workflow, pathFilterName}) => {
+      github.actions.createWorkflowDispatch({
+        owner: 'getsentry',
+        repo: 'getsentry',
+        workflow_id: workflow,
+        ref: 'master',
+        inputs: {
+          pull_request_number: `${context.payload.pull_request.number}`, // needs to be string
+          skip: `${shouldSkip[pathFilterName]}`, // even though this is a boolean, it must be cast to a string
+          'sentry-sha': context.payload.pull_request.head.sha,
+        },
+      });
+    });
+  },
+};