From a8da2a66aae3085f1d5ca820e8e5ca85120670fc Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Wed, 27 Apr 2022 11:28:44 +0500 Subject: [PATCH 1/7] Use /opt/hostedtoolcache as default value AGENT_TOOLSDIRECTORY --- dist/setup/index.js | 127 ++++++++++++++++++++++++++++++++++++++++++++ src/setup-python.ts | 15 +++--- 2 files changed, 133 insertions(+), 9 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 3c417588f..44f8ed5df 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -5225,10 +5225,137 @@ class ToolRunner extends events.EventEmitter { return (this._endsWith(upperToolPath, '.CMD') || this._endsWith(upperToolPath, '.BAT')); } +<<<<<<< HEAD _windowsQuoteCmdArg(arg) { // for .exe, apply the normal quoting rules that libuv applies if (!this._isCmdFile()) { return this._uvQuoteCmdArg(arg); +======= + + const sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + const sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + const sameSemVer = this.semver.version === comp.semver.version + const differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + const oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<') + const oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>') + + return ( + sameDirectionIncreasing || + sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || + oppositeDirectionsGreaterThan + ) + } +} + +module.exports = Comparator + +const {re, t} = __webpack_require__(328) +const cmp = __webpack_require__(752) +const debug = __webpack_require__(548) +const SemVer = __webpack_require__(206) +const Range = __webpack_require__(124) + + +/***/ }), +/* 175 */ +/***/ (function(__unusedmodule, exports, __webpack_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 }); +const core = __importStar(__webpack_require__(470)); +const finder = __importStar(__webpack_require__(927)); +const finderPyPy = __importStar(__webpack_require__(847)); +const path = __importStar(__webpack_require__(622)); +const os = __importStar(__webpack_require__(87)); +const cache_factory_1 = __webpack_require__(633); +const utils_1 = __webpack_require__(163); +function isPyPyVersion(versionSpec) { + return versionSpec.startsWith('pypy-'); +} +function cacheDependencies(cache, pythonVersion) { + return __awaiter(this, void 0, void 0, function* () { + const cacheDependencyPath = core.getInput('cache-dependency-path') || undefined; + const cacheDistributor = cache_factory_1.getCacheDistributor(cache, pythonVersion, cacheDependencyPath); + yield cacheDistributor.restoreCache(); + }); +} +function run() { + var _a; + return __awaiter(this, void 0, void 0, function* () { + if (!((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim())) { + process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; + } + core.debug(`Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}`); + process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; + try { + const version = core.getInput('python-version'); + if (version) { + let pythonVersion; + const arch = core.getInput('architecture') || os.arch(); + if (isPyPyVersion(version)) { + const installed = yield finderPyPy.findPyPyVersion(version, arch); + pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; + core.info(`Successfully setup PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); + } + else { + const installed = yield finder.useCpythonVersion(version, arch); + pythonVersion = installed.version; + core.info(`Successfully setup ${installed.impl} (${pythonVersion})`); + } + const cache = core.getInput('cache'); + if (cache && utils_1.isCacheFeatureAvailable()) { + yield cacheDependencies(cache, pythonVersion); + } + } + else { + throw new Error("there's empty python-version input"); + } + const matchersPath = path.join(__dirname, '../..', '.github'); + core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`); +>>>>>>> 99015f8 (Use /opt/hostedtoolcache as default value AGENT_TOOLSDIRECTORY) } // otherwise apply quoting rules specific to the cmd.exe command line parser. // the libuv rules are generic and are not designed specifically for cmd.exe diff --git a/src/setup-python.ts b/src/setup-python.ts index 2ffeb1ade..a3dd0607d 100644 --- a/src/setup-python.ts +++ b/src/setup-python.ts @@ -49,16 +49,13 @@ function resolveVersionInput(): string { } async function run() { - if (process.env.AGENT_TOOLSDIRECTORY?.trim()) { - core.debug( - `Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}` - ); - process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; - } else { - core.debug( - `Python is expected to be installed into RUNNER_TOOL_CACHE==${process.env['RUNNER_TOOL_CACHE']}` - ); + if (!process.env.AGENT_TOOLSDIRECTORY?.trim()) { + process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; } + core.debug( + `Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}` + ); + process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; try { const version = resolveVersionInput(); if (version) { From 5ad79022bcf7697f57275899d0f60e4afbdea17d Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Thu, 28 Apr 2022 12:14:49 +0500 Subject: [PATCH 2/7] Change README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5968fdc6..bc257ab4f 100644 --- a/README.md +++ b/README.md @@ -337,7 +337,7 @@ If you are experiencing problems while configuring Python on your self-hosted ru ### Linux - The Python packages that are downloaded from `actions/python-versions` are originally compiled from source in `/opt/hostedtoolcache/` with the [--enable-shared](https://github.com/actions/python-versions/blob/94f04ae6806c6633c82db94c6406a16e17decd5c/builders/ubuntu-python-builder.psm1#L35) flag, which makes them non-relocatable. -- Create an environment variable called `AGENT_TOOLSDIRECTORY` and set it to `/opt/hostedtoolcache`. This controls where the runner downloads and installs tools. +- By default runner downloads and install the tools to `/opt/hostedtoolcache`. The environment variable called `AGENT_TOOLSDIRECTORY` can be set to change this location. - In the same shell that your runner is using, type `export AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache`. - A more permanent way of setting the environment variable is to create a `.env` file in the same directory as your runner and to add `AGENT_TOOLSDIRECTORY=/opt/hostedtoolcache`. This ensures the variable is always set if your runner is configured as a service. - Create a directory called `hostedtoolcache` inside `/opt`. From 7199395312a0a82b9c1b42a0e147408b89071ca6 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Thu, 5 May 2022 21:01:59 +0500 Subject: [PATCH 3/7] Fix dist folder --- dist/setup/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 44f8ed5df..e4c60af88 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -5350,9 +5350,6 @@ function run() { yield cacheDependencies(cache, pythonVersion); } } - else { - throw new Error("there's empty python-version input"); - } const matchersPath = path.join(__dirname, '../..', '.github'); core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`); >>>>>>> 99015f8 (Use /opt/hostedtoolcache as default value AGENT_TOOLSDIRECTORY) From 5d9fdcab75b9ab9c36a00d14742e5d54dcbb8e42 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Fri, 6 May 2022 09:09:02 +0500 Subject: [PATCH 4/7] Handle each OS in its own way --- dist/setup/index.js | 7 +++++-- src/setup-python.ts | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index e4c60af88..06dada78a 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -5325,8 +5325,11 @@ function cacheDependencies(cache, pythonVersion) { function run() { var _a; return __awaiter(this, void 0, void 0, function* () { - if (!((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim())) { - process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; + if (!utils_1.IS_WINDOWS && !((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim())) { + if (utils_1.IS_LINUX) + process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; + else + process.env['AGENT_TOOLSDIRECTORY'] = '/Users/runner/hostedtoolcache'; } core.debug(`Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}`); process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; diff --git a/src/setup-python.ts b/src/setup-python.ts index a3dd0607d..0b1553b09 100644 --- a/src/setup-python.ts +++ b/src/setup-python.ts @@ -5,7 +5,7 @@ import * as path from 'path'; import * as os from 'os'; import fs from 'fs'; import {getCacheDistributor} from './cache-distributions/cache-factory'; -import {isCacheFeatureAvailable} from './utils'; +import {isCacheFeatureAvailable, IS_LINUX, IS_WINDOWS} from './utils'; function isPyPyVersion(versionSpec: string) { return versionSpec.startsWith('pypy'); @@ -49,8 +49,9 @@ function resolveVersionInput(): string { } async function run() { - if (!process.env.AGENT_TOOLSDIRECTORY?.trim()) { - process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; + if (!IS_WINDOWS && !process.env.AGENT_TOOLSDIRECTORY?.trim()) { + if (IS_LINUX) process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; + else process.env['AGENT_TOOLSDIRECTORY'] = '/Users/runner/hostedtoolcache'; } core.debug( `Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}` From 958897304aea586672b0085b6b9031f928b11961 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Fri, 6 May 2022 09:26:48 +0500 Subject: [PATCH 5/7] Exclude windows from the fix --- dist/setup/index.js | 6 ++++-- src/setup-python.ts | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 06dada78a..6d75cc200 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -5325,14 +5325,16 @@ function cacheDependencies(cache, pythonVersion) { function run() { var _a; return __awaiter(this, void 0, void 0, function* () { + // According to the README windows binaries do not require to be installed + // in the specific location, but Mac and Linux do if (!utils_1.IS_WINDOWS && !((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim())) { if (utils_1.IS_LINUX) process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; else process.env['AGENT_TOOLSDIRECTORY'] = '/Users/runner/hostedtoolcache'; + process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; } - core.debug(`Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}`); - process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; + core.debug(`Python is expected to be installed into RUNNER_TOOL_CACHE=${process.env['RUNNER_TOOL_CACHE']}`); try { const version = core.getInput('python-version'); if (version) { diff --git a/src/setup-python.ts b/src/setup-python.ts index 0b1553b09..20bc8ffeb 100644 --- a/src/setup-python.ts +++ b/src/setup-python.ts @@ -49,14 +49,16 @@ function resolveVersionInput(): string { } async function run() { + // According to the README windows binaries do not require to be installed + // in the specific location, but Mac and Linux do if (!IS_WINDOWS && !process.env.AGENT_TOOLSDIRECTORY?.trim()) { if (IS_LINUX) process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; else process.env['AGENT_TOOLSDIRECTORY'] = '/Users/runner/hostedtoolcache'; + process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; } core.debug( - `Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}` + `Python is expected to be installed into RUNNER_TOOL_CACHE=${process.env['RUNNER_TOOL_CACHE']}` ); - process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; try { const version = resolveVersionInput(); if (version) { From 9c76df2a906d23390826e21a05ccb6e3abbbda34 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Wed, 29 Jun 2022 11:24:02 +0200 Subject: [PATCH 6/7] Build after rebase --- dist/setup/index.js | 142 +++----------------------------------------- 1 file changed, 8 insertions(+), 134 deletions(-) diff --git a/dist/setup/index.js b/dist/setup/index.js index 6d75cc200..8c554859d 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -5225,139 +5225,10 @@ class ToolRunner extends events.EventEmitter { return (this._endsWith(upperToolPath, '.CMD') || this._endsWith(upperToolPath, '.BAT')); } -<<<<<<< HEAD _windowsQuoteCmdArg(arg) { // for .exe, apply the normal quoting rules that libuv applies if (!this._isCmdFile()) { return this._uvQuoteCmdArg(arg); -======= - - const sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - const sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - const sameSemVer = this.semver.version === comp.semver.version - const differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - const oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<') - const oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>') - - return ( - sameDirectionIncreasing || - sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || - oppositeDirectionsGreaterThan - ) - } -} - -module.exports = Comparator - -const {re, t} = __webpack_require__(328) -const cmp = __webpack_require__(752) -const debug = __webpack_require__(548) -const SemVer = __webpack_require__(206) -const Range = __webpack_require__(124) - - -/***/ }), -/* 175 */ -/***/ (function(__unusedmodule, exports, __webpack_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 }); -const core = __importStar(__webpack_require__(470)); -const finder = __importStar(__webpack_require__(927)); -const finderPyPy = __importStar(__webpack_require__(847)); -const path = __importStar(__webpack_require__(622)); -const os = __importStar(__webpack_require__(87)); -const cache_factory_1 = __webpack_require__(633); -const utils_1 = __webpack_require__(163); -function isPyPyVersion(versionSpec) { - return versionSpec.startsWith('pypy-'); -} -function cacheDependencies(cache, pythonVersion) { - return __awaiter(this, void 0, void 0, function* () { - const cacheDependencyPath = core.getInput('cache-dependency-path') || undefined; - const cacheDistributor = cache_factory_1.getCacheDistributor(cache, pythonVersion, cacheDependencyPath); - yield cacheDistributor.restoreCache(); - }); -} -function run() { - var _a; - return __awaiter(this, void 0, void 0, function* () { - // According to the README windows binaries do not require to be installed - // in the specific location, but Mac and Linux do - if (!utils_1.IS_WINDOWS && !((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim())) { - if (utils_1.IS_LINUX) - process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; - else - process.env['AGENT_TOOLSDIRECTORY'] = '/Users/runner/hostedtoolcache'; - process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; - } - core.debug(`Python is expected to be installed into RUNNER_TOOL_CACHE=${process.env['RUNNER_TOOL_CACHE']}`); - try { - const version = core.getInput('python-version'); - if (version) { - let pythonVersion; - const arch = core.getInput('architecture') || os.arch(); - if (isPyPyVersion(version)) { - const installed = yield finderPyPy.findPyPyVersion(version, arch); - pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; - core.info(`Successfully setup PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); - } - else { - const installed = yield finder.useCpythonVersion(version, arch); - pythonVersion = installed.version; - core.info(`Successfully setup ${installed.impl} (${pythonVersion})`); - } - const cache = core.getInput('cache'); - if (cache && utils_1.isCacheFeatureAvailable()) { - yield cacheDependencies(cache, pythonVersion); - } - } - const matchersPath = path.join(__dirname, '../..', '.github'); - core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`); ->>>>>>> 99015f8 (Use /opt/hostedtoolcache as default value AGENT_TOOLSDIRECTORY) } // otherwise apply quoting rules specific to the cmd.exe command line parser. // the libuv rules are generic and are not designed specifically for cmd.exe @@ -64693,13 +64564,16 @@ function resolveVersionInput() { function run() { var _a; return __awaiter(this, void 0, void 0, function* () { - if ((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim()) { - core.debug(`Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}`); + // According to the README windows binaries do not require to be installed + // in the specific location, but Mac and Linux do + if (!utils_1.IS_WINDOWS && !((_a = process.env.AGENT_TOOLSDIRECTORY) === null || _a === void 0 ? void 0 : _a.trim())) { + if (utils_1.IS_LINUX) + process.env['AGENT_TOOLSDIRECTORY'] = '/opt/hostedtoolcache'; + else + process.env['AGENT_TOOLSDIRECTORY'] = '/Users/runner/hostedtoolcache'; process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; } - else { - core.debug(`Python is expected to be installed into RUNNER_TOOL_CACHE==${process.env['RUNNER_TOOL_CACHE']}`); - } + core.debug(`Python is expected to be installed into RUNNER_TOOL_CACHE=${process.env['RUNNER_TOOL_CACHE']}`); try { const version = resolveVersionInput(); if (version) { From 96f494e18c81869c9d5eef39102df0b23b2bc4f2 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Fri, 1 Jul 2022 10:28:46 +0200 Subject: [PATCH 7/7] trigger checks