Skip to content

Commit

Permalink
Merge pull request #26 from paleite/check-for-ci
Browse files Browse the repository at this point in the history
Check for CI
  • Loading branch information
paleite authored Aug 1, 2022
2 parents 2db4474 + 6eff482 commit 6df64b0
Show file tree
Hide file tree
Showing 18 changed files with 622 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const typescriptProjects = ["./tsconfig.json", "./tsconfig.eslint.json"];
/** @type import("eslint").Linter.Config */
module.exports = {
root: true,
extends: ["@paleite", "plugin:diff/diff"],
extends: ["@paleite", "plugin:diff/ci"],
parserOptions: { project: typescriptProjects, tsconfigRootDir: __dirname },
overrides: [
{
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/eslint-plugin-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,5 @@ jobs:
run: |
yarn link
yarn link "eslint-plugin-diff"
- name: Fetch the base branch
run: git fetch origin ${{ github.event.pull_request.base.ref }}:${{ github.event.pull_request.base.ref }}
- name: Run ESLint on your changes only
env:
ESLINT_PLUGIN_DIFF_COMMIT: ${{ github.event.pull_request.base.ref }}
run: npx --no-install eslint --ext .js,.jsx,.ts,.tsx .
run: yarn run lint
37 changes: 32 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,47 @@ yarn add -D eslint eslint-plugin-diff

### Extend config

Extend your ESLint config with `"plugin:diff/diff"`:
Extend your ESLint config with one of our configs.

#### `"plugin:diff/diff"` (recommended)

Only lint changes

```json
{
"extends": ["plugin:diff/diff"]
}
```

You can also choose `"plugin:diff/staged"` if you prefer to lint only staged
files.
#### `"plugin:diff/ci"`

In a CI-environment, only lint changes. Locally, skip the plugin (i.e. lint everything).

> NOTE: This requires the environment variable `CI` to be defined, which most CI-provides set automatically.
```json
{
"extends": ["plugin:diff/ci"]
}
```

#### `"plugin:diff/staged"`

Only lint the changes you've staged for an upcoming commit.

```json
{
"extends": ["plugin:diff/staged"]
}
```

## Enable the plugin in CI only

If you want to enable the plugin in CI only, you can use extend the config with the the plugin locally, but enable it

## CI Setup

To lint all the changes of a PR, you only have to set
To lint all the changes of a pull-request, you only have to set
`ESLINT_PLUGIN_DIFF_COMMIT` before running ESLint.

### For GitHub Actions
Expand All @@ -65,7 +92,7 @@ jobs:
- uses: actions/checkout@v3
- name: Install modules
run: npm install
- name: Fetch the base branch
- name: Fetch the base branch, so we can use `git diff`
run: git fetch origin ${{ github.event.pull_request.base.ref }}:${{ github.event.pull_request.base.ref }}
- name: Run ESLint on your changes only
env:
Expand Down
9 changes: 5 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ const { base } = require("@paleite/jest-config");
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
...base,
coveragePathIgnorePatterns: [".test-d.ts"],
coverageThreshold: {
global: {
branches: 75,
functions: 80,
lines: 80,
statements: 80,
statements: 90,
branches: 90,
functions: 90,
lines: 90,
},
},
};
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@typescript-eslint/parser": "^5.27.0",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^3.3.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.0.0",
"husky": "^8.0.1",
Expand All @@ -69,6 +70,7 @@
"size-limit": "^7.0.8",
"terser": "^5.14.2",
"ts-jest": "^28.0.4",
"tsd": "^0.22.0",
"typescript": "^4.7.3"
},
"peerDependencies": {
Expand Down
9 changes: 0 additions & 9 deletions src/__fixtures__/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,12 @@ index cb3c131..874b8f9 100644
-import { b } from "../context/b";
-import { c } from "../context/c";`;

const filenamesAB = `a/dirty.js
b/dirty.js
`;

const filenamesA = `a/dirty.js
`;

const diffFileList = "file1\nfile2\nfile3\n";

export {
diff,
staged,
hunks,
includingOnlyRemovals,
filenamesAB,
filenamesA,
diffFileList,
};
18 changes: 18 additions & 0 deletions src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

exports[`plugin should match expected export 1`] = `
Object {
"ci": Object {
"overrides": Array [
Object {
"files": Array [
"*",
],
"processor": "diff/ci",
},
],
"plugins": Array [
"diff",
],
},
"diff": Object {
"overrides": Array [
Object {
Expand Down Expand Up @@ -33,6 +46,11 @@ Object {

exports[`plugin should match expected export 2`] = `
Object {
"ci": Object {
"postprocess": [Function],
"preprocess": [Function],
"supportsAutofix": true,
},
"diff": Object {
"postprocess": [Function],
"preprocess": [Function],
Expand Down
5 changes: 5 additions & 0 deletions src/ci.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { expectType } from "tsd";
import type { CiProvider, CiProviderName } from "./ci";
import { PROVIDERS } from "./ci";

expectType<Record<CiProviderName, CiProvider>>(PROVIDERS);
125 changes: 125 additions & 0 deletions src/ci.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const OLD_ENV = process.env;

beforeEach(() => {
jest.resetModules(); // Most important - it clears the cache
process.env = { ...OLD_ENV }; // Make a copy
});

describe("guessBranch", () => {
it("ensure the branch is guessed if ESLINT_PLUGIN_COMMIT is not already set", async () => {
delete process.env.ESLINT_PLUGIN_COMMIT;
const { guessBranch } = await import("./ci");
expect(() => guessBranch()).not.toThrowError(/ESLINT_PLUGIN_COMMIT/u);
});

it("ensure the branch is not guessed if ESLINT_PLUGIN_COMMIT is already set", async () => {
process.env.ESLINT_PLUGIN_COMMIT = "origin/main";
const { guessBranch } = await import("./ci");
expect(() => guessBranch()).toThrowError(/ESLINT_PLUGIN_COMMIT/u);
});

it("fails when too many providers were found as candidates", async () => {
process.env.SYSTEM_PULLREQUEST_TARGETBRANCH = "CORRECT";
process.env.bamboo_repository_pr_targetBranch = "CORRECT";
process.env.BITBUCKET_PR_DESTINATION_BRANCH = "CORRECT";
process.env.BUDDY_EXECUTION_PULL_REQUEST_BASE_BRANCH = "CORRECT";
process.env.DRONE_TARGET_BRANCH = "CORRECT";
process.env.GITHUB_BASE_REF = "CORRECT";
process.env.APPVEYOR_PULL_REQUEST_NUMBER = "0";
process.env.APPVEYOR_REPO_BRANCH = "CORRECT";
process.env.CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME = "CORRECT";
process.env.TRAVIS_BRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(() => guessBranch()).toThrowError(/Too many CI providers found/u);
});
});

describe("simple supported providers", () => {
it("AzurePipelines", async () => {
process.env.SYSTEM_PULLREQUEST_TARGETBRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("Bamboo", async () => {
process.env.bamboo_repository_pr_targetBranch = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("BitbucketPipelines", async () => {
process.env.BITBUCKET_PR_DESTINATION_BRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("Buddy", async () => {
process.env.BUDDY_EXECUTION_PULL_REQUEST_BASE_BRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("Drone", async () => {
process.env.DRONE_TARGET_BRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("GitHubActions", async () => {
process.env.GITHUB_BASE_REF = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});
});

describe("complex supported providers", () => {
it("AppVeyor", async () => {
// APPVEYOR_PULL_REQUEST_NUMBER is non-empty, so we can find the repo in
// APPVEYOR_REPO_BRANCH
process.env.APPVEYOR_PULL_REQUEST_NUMBER = "0";
process.env.APPVEYOR_REPO_BRANCH = "CORRECT";

const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("doesn't return the guessed branch when APPVEYOR_PULL_REQUEST_NUMBER is empty", async () => {
// APPVEYOR_PULL_REQUEST_NUMBER is non-empty iff we're in a pull-request.
delete process.env.APPVEYOR_PULL_REQUEST_NUMBER;
// Scenario: A regular commit to main, not a pull-request.
process.env.APPVEYOR_REPO_BRANCH = "main";

const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe(undefined);
});

it("GitLab with CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME", async () => {
delete process.env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
process.env.CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("GitLab with CI_MERGE_REQUEST_TARGET_BRANCH_NAME", async () => {
delete process.env.CI_EXTERNAL_PULL_REQUEST_TARGET_BRANCH_NAME;
process.env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("Travis", async () => {
delete process.env.TRAVIS_PULL_REQUEST;
process.env.TRAVIS_BRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe("CORRECT");
});

it("doesn't return the guessed branch when TRAVIS_PULL_REQUEST is explicitly 'false'", async () => {
process.env.TRAVIS_PULL_REQUEST = "false";
process.env.TRAVIS_BRANCH = "CORRECT";
const { guessBranch } = await import("./ci");
expect(guessBranch()).toBe(undefined);
});
});

export {};
Loading

0 comments on commit 6df64b0

Please sign in to comment.