Skip to content

Commit

Permalink
Merge pull request #383 from gradle-update/paths-input
Browse files Browse the repository at this point in the history
Introduce `paths` and `paths-ignore` inputs.
  • Loading branch information
cristiangreco authored Jan 19, 2022
2 parents 43a4527 + d4a61bc commit 52e7f94
Show file tree
Hide file tree
Showing 10 changed files with 422 additions and 21 deletions.
97 changes: 95 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ your projects up-to-date to the latest release.

Schedule an automatic daily or weekly workflow: as soon
as a new Gradle release is available, the action will open a PR ready to be
merged. It's like [Dependabot](https://dependabot.com) for Gradle Wrapper. 🤖✨
merged. It's like [Dependabot](https://github.com/dependabot) for Gradle Wrapper. 🤖✨

![Pull
Request](https://user-images.githubusercontent.com/316923/93274006-8922ef80-f7b9-11ea-8ec7-85c2704270eb.png
Expand All @@ -25,10 +25,14 @@ Request](https://user-images.githubusercontent.com/316923/93274006-8922ef80-f7b9
- [`labels`](#labels)
- [`base-branch`](#base-branch)
- [`target-branch`](#target-branch)
- [`paths`](#paths)
- [`paths-ignore`](#paths-ignore)
- [`set-distribution-checksum`](#set-distribution-checksum)
- [Examples](#examples)
- [Scheduling action execution](#scheduling-action-execution)
- [Targeting a custom branch](#targeting-a-custom-branch)
- [Ignoring subprojects folders](#ignoring-subproject-folders)
- [Using `paths` and `paths-ignore` together](#using-paths-and-paths-ignore-together)
- [FAQ](#faq)
- [Running CI workflows in Pull Requests created by the action](#running-ci-workflows-in-pull-requests-created-by-the-action)
- [Android Studio warning about `distributionSha256Sum`](#android-studio-warning-about-distributionsha256sum)
Expand Down Expand Up @@ -128,9 +132,11 @@ This is the list of supported inputs:
| [`repo-token`](#repo-token) | `GITHUB_TOKEN` or a Personal Access Token (PAT) with `repo` scope. | No | `GITHUB_TOKEN` |
| [`reviewers`](#reviewers) | List of users to request a review from (comma or newline-separated). | No | (empty) |
| [`team-reviewers`](#team-reviewers) | List of teams to request a review from (comma or newline-separated). | No | (empty) |
| [`labels`](#labels) | 'List of labels to set on the Pull Request (comma or newline-separated). | No | (empty) |
| [`labels`](#labels) | List of labels to set on the Pull Request (comma or newline-separated). | No | (empty) |
| [`base-branch`](#base-branch) | Base branch where the action will run and update the Gradle Wrapper. | No | The default branch name of your repository. |
| [`target-branch`](#target-branch) | Branch to create the Pull Request against. | No | The default branch name of your repository. |
| [`paths`](#paths) | List of paths where to search for Gradle Wrapper files (comma or newline-separated). | No | (empty) |
| [`paths-ignore`](#paths-ignore) | List of paths to be excluded when searching for Gradle Wrapper files (comma or newline-separated). | No | (empty) |
| [`set-distribution-checksum`](#set-distribution-checksum) | Whether to set the `distributionSha256Sum` property. | No | `true` |

---
Expand Down Expand Up @@ -293,6 +299,66 @@ with:

---

### `paths`

| Name | Description | Required | Default |
| --- | --- | --- | --- |
| `paths` | List of paths where to search for Gradle Wrapper files (comma or newline-separated). | No | (empty) |

By default all Gradle Wrapper files in the source tree will be autodiscovered and considered for update. Use `paths` to provide a specific list of paths where to look for `gradle-wrapper.jar`.

For example, use a comma-separated list:

```yaml
with:
paths: project-web/**, project-backend/**
```

or add each path on a different line (no comma needed):

```yaml
with:
paths: |
project-web/**
project-backend/**
```

This input accepts glob patterns that use characters like `*` and `**`, for more information see [GitHub's cheat sheet](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet).

`paths` and `paths-ignore` can be used together. `paths` is always evaluated before `paths-ignore`, look at [this example](#using-paths-and-paths-ignore-together).

---

### `paths-ignore`

| Name | Description | Required | Default |
| --- | --- | --- | --- |
| `paths-ignore` | List of paths to be excluded when searching for Gradle Wrapper files (comma or newline-separated). | No | (empty) |

By default all Gradle Wrapper files in the source tree will be autodiscovered and considered for update. Use `paths-ignore` to specify paths that should be ignored during scan.

For example, use a comma-separated list:

```yaml
with:
paths-ignore: project-docs/**, project-examples/**
```

or add each path on a different line (no comma needed):

```yaml
with:
paths-ignore: |
project-docs/**
project-examples/**
```

This input accepts glob patterns that use characters like `*` and `**`, for more information see [GitHub's cheat sheet](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet).

`paths` and `paths-ignore` can be used together. `paths-ignore` is always evaluated after `paths`, look at [this example](#using-paths-and-paths-ignore-together).

---

### `set-distribution-checksum`

| Name | Description | Required | Default |
Expand Down Expand Up @@ -362,6 +428,33 @@ with:
target-branch: v2-dev
```

### Ignoring subprojects folders

There are cases where your repository contains folders for projects or subprojects that need to be kept at an older Gradle version.

If you want to ignore such files when the action runs, use `paths-ignore` to configure project paths that contains Gradle Wrapper files that should not be updated.

```yaml
with:
paths-ignore: examples/**
```

### Using `paths` and `paths-ignore` together

`paths` and `paths-ignore` works as allowlist and blocklist systems. The evaluation rule is as follows:

- the source tree is searched for all `gradle-wrapper.jar` files and the list is passed to the next step
- if `paths` is not empty, the paths that match the specified patterns are passed to the next step
- if `paths-ignore` is not empty, the paths that match the specified patterns are removed from the list

For example, the following configuration will srarch for Gradle Wrapper files in the `sub-project` directory and its subdirectories, but not in the `sub-project/examples` directory.

```yaml
with:
paths: sub-project/**
paths-ignore: sub-project/examples/**
```

## FAQ

### Running CI workflows in Pull Requests created by the action
Expand Down
8 changes: 8 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ inputs:
description: 'Whether to set the `distributionSha256Sum` property in `gradle-wrapper.properties`.'
required: false
default: true
paths:
description: 'List of paths where to search for Gradle Wrapper files (comma or newline-separated).'
required: false
default: ''
paths-ignore:
description: 'List of paths to be excluded when searching for Gradle Wrapper files (comma or newline-separated).'
required: false
default: ''

runs:
using: 'node16'
Expand Down
102 changes: 99 additions & 3 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,16 @@ class ActionInputs {
core
.getInput('set-distribution-checksum', { required: false })
.toLowerCase() !== 'false';
this.paths = core
.getInput('paths', { required: false })
.split(/[\n,]/)
.map(r => r.trim())
.filter(r => r.length);
this.pathsIgnore = core
.getInput('paths-ignore', { required: false })
.split(/[\n,]/)
.map(r => r.trim())
.filter(r => r.length);
}
}

Expand Down Expand Up @@ -978,13 +988,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MainAction = void 0;
const core = __importStar(__nccwpck_require__(2186));
const glob = __importStar(__nccwpck_require__(8090));
const git = __importStar(__nccwpck_require__(8940));
const gitAuth = __importStar(__nccwpck_require__(1304));
const store = __importStar(__nccwpck_require__(5826));
const git_commit_1 = __nccwpck_require__(4779);
const wrapperInfo_1 = __nccwpck_require__(6832);
const wrapperUpdater_1 = __nccwpck_require__(7412);
const find_1 = __nccwpck_require__(2758);
class MainAction {
constructor(inputs, githubApi, githubOps, releases) {
this.inputs = inputs;
Expand All @@ -1008,8 +1018,7 @@ class MainAction {
core.warning(`A pull request already exists that updates Gradle Wrapper to ${targetRelease.version}.`);
return;
}
const globber = yield glob.create('**/gradle/wrapper/gradle-wrapper.properties', { followSymbolicLinks: false });
const wrappers = yield globber.glob();
const wrappers = yield (0, find_1.findWrapperPropertiesFiles)(this.inputs.paths, this.inputs.pathsIgnore);
core.debug(`Wrappers: ${JSON.stringify(wrappers, null, 2)}`);
if (!wrappers.length) {
core.warning('Unable to find Gradle Wrapper files in this project.');
Expand Down Expand Up @@ -1201,6 +1210,93 @@ and [\`team-reviewers\`](https://github.com/gradle-update/update-gradle-wrapper-
exports.PostAction = PostAction;


/***/ }),

/***/ 2758:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {

"use strict";

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.findWrapperPropertiesFiles = void 0;
const core = __importStar(__nccwpck_require__(2186));
const glob = __importStar(__nccwpck_require__(8090));
const internal_match_kind_1 = __nccwpck_require__(1063);
const internal_pattern_1 = __nccwpck_require__(4536);
function findWrapperPropertiesFiles(pathsInclude, pathsIgnore) {
return __awaiter(this, void 0, void 0, function* () {
const globber = yield glob.create('**/gradle/wrapper/gradle-wrapper.properties', { followSymbolicLinks: false });
let propertiesFiles = yield globber.glob();
core.debug(`wrapper.properties found: ${JSON.stringify(propertiesFiles, null, 2)}`);
if (!propertiesFiles.length) {
return propertiesFiles;
}
if (pathsInclude.length) {
const toInclude = [];
for (const wrapperPath of propertiesFiles) {
let shouldInclude = false;
for (const searchPath of pathsInclude) {
const pattern = new internal_pattern_1.Pattern(searchPath);
const match = pattern.match(wrapperPath);
shouldInclude || (shouldInclude = match === internal_match_kind_1.MatchKind.All);
}
if (shouldInclude) {
toInclude.push(wrapperPath);
}
}
propertiesFiles = toInclude;
}
core.debug(`wrapper.properties after pathsInclude: ${JSON.stringify(propertiesFiles, null, 2)}`);
if (pathsIgnore.length) {
const toExclude = [];
for (const wrapperPath of propertiesFiles) {
let shouldExclude = false;
for (const searchPath of pathsIgnore) {
const pattern = new internal_pattern_1.Pattern(searchPath);
const match = pattern.match(wrapperPath);
shouldExclude || (shouldExclude = match === internal_match_kind_1.MatchKind.All);
}
if (shouldExclude) {
toExclude.push(wrapperPath);
}
}
propertiesFiles = propertiesFiles.filter(f => !toExclude.includes(f));
}
core.debug(`wrapper.properties after pathsExclude: ${JSON.stringify(propertiesFiles, null, 2)}`);
return propertiesFiles;
});
}
exports.findWrapperPropertiesFiles = findWrapperPropertiesFiles;


/***/ }),

/***/ 6832:
Expand Down
16 changes: 16 additions & 0 deletions src/inputs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface Inputs {
baseBranch: string;
targetBranch: string;
setDistributionChecksum: boolean;
paths: string[];
pathsIgnore: string[];
}

export function getInputs(): Inputs {
Expand All @@ -36,6 +38,8 @@ class ActionInputs implements Inputs {
baseBranch: string;
targetBranch: string;
setDistributionChecksum: boolean;
paths: string[];
pathsIgnore: string[];

constructor() {
this.repoToken = core.getInput('repo-token', {required: false});
Expand Down Expand Up @@ -69,5 +73,17 @@ class ActionInputs implements Inputs {
core
.getInput('set-distribution-checksum', {required: false})
.toLowerCase() !== 'false';

this.paths = core
.getInput('paths', {required: false})
.split(/[\n,]/)
.map(r => r.trim())
.filter(r => r.length);

this.pathsIgnore = core
.getInput('paths-ignore', {required: false})
.split(/[\n,]/)
.map(r => r.trim())
.filter(r => r.length);
}
}
9 changes: 4 additions & 5 deletions src/tasks/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.

import * as core from '@actions/core';
import * as glob from '@actions/glob';

import * as git from '../git/git-cmds';
import * as gitAuth from '../git/git-auth';
Expand All @@ -22,6 +21,7 @@ import * as store from '../store';
import {commit} from '../git/git-commit';
import {createWrapperInfo} from '../wrapperInfo';
import {createWrapperUpdater} from '../wrapperUpdater';
import {findWrapperPropertiesFiles} from '../wrapper/find';
import {GitHubOps} from '../github/gh-ops';
import {IGitHubApi} from '../github/gh-api';
import {Inputs} from '../inputs';
Expand Down Expand Up @@ -68,11 +68,10 @@ export class MainAction {
return;
}

const globber = await glob.create(
'**/gradle/wrapper/gradle-wrapper.properties',
{followSymbolicLinks: false}
const wrappers = await findWrapperPropertiesFiles(
this.inputs.paths,
this.inputs.pathsIgnore
);
const wrappers = await globber.glob();
core.debug(`Wrappers: ${JSON.stringify(wrappers, null, 2)}`);

if (!wrappers.length) {
Expand Down
Loading

0 comments on commit 52e7f94

Please sign in to comment.