cronjob
parent
f3cbb79e40
commit
ebfa50648e
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1078,6 +1078,31 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|||
IN THE SOFTWARE.
|
||||
|
||||
|
||||
cron-converter
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2016 Rouslan Placella (https://github.com/roccivic)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
cross-spawn
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
|
@ -2204,6 +2229,55 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
|
||||
|
||||
moment
|
||||
MIT
|
||||
Copyright (c) JS Foundation and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
moment-timezone
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) JS Foundation and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
nanoid
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
|
@ -2967,6 +3041,34 @@ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
sprintf-js
|
||||
BSD-3-Clause
|
||||
Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of this software nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
sshpk
|
||||
MIT
|
||||
Copyright Joyent, Inc. All rights reserved.
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"async-wait-until": "^2.0.7",
|
||||
"aws-sdk": "^2.812.0",
|
||||
"base-64": "^1.0.0",
|
||||
"cron-converter": "^1.0.1",
|
||||
"nanoid": "3.1.20",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import KubernetesLogging from './kubernetes-logging';
|
|||
import KubernetesSecret from './kubernetes-secret';
|
||||
import KubernetesUtilities from './kubernetes-utils';
|
||||
import waitUntil from 'async-wait-until';
|
||||
import KubernetesJobSpecFactory from './kubernetes-job-spec-factory';
|
||||
import KubernetesCleanupCronJob from './kubernetes-cleanup-cronjob';
|
||||
|
||||
class Kubernetes implements RemoteBuilderProviderInterface {
|
||||
private kubeConfig: k8s.KubeConfig;
|
||||
|
|
@ -22,18 +24,17 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
|||
private namespace: string;
|
||||
private podName: string = '';
|
||||
private containerName: string = '';
|
||||
private cleanupCronJobName: string = '';
|
||||
private kubeClientBatchBeta: k8s.BatchV1beta1Api;
|
||||
|
||||
constructor(buildParameters: BuildParameters) {
|
||||
const kc = new k8s.KubeConfig();
|
||||
kc.loadFromDefault();
|
||||
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
|
||||
const k8sBatchApi = kc.makeApiClient(k8s.BatchV1Api);
|
||||
this.kubeConfig = new k8s.KubeConfig();
|
||||
this.kubeConfig.loadFromDefault();
|
||||
this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
|
||||
this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
|
||||
this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api);
|
||||
core.info('Loaded default Kubernetes configuration for this environment');
|
||||
|
||||
this.kubeConfig = kc;
|
||||
this.kubeClient = k8sApi;
|
||||
this.kubeClientBatch = k8sBatchApi;
|
||||
|
||||
this.namespace = 'default';
|
||||
this.buildParameters = buildParameters;
|
||||
}
|
||||
|
|
@ -45,9 +46,14 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
|||
// eslint-disable-next-line no-unused-vars
|
||||
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
|
||||
) {
|
||||
const pvcName = `unity-builder-pvc-${buildUid}`;
|
||||
this.pvcName = pvcName;
|
||||
this.pvcName = `unity-builder-pvc-${buildUid}`;
|
||||
this.cleanupCronJobName = `unity-builder-cronjob-${buildUid}`;
|
||||
await KubernetesStorage.createPersistentVolumeClaim(buildParameters, this.pvcName, this.kubeClient, this.namespace);
|
||||
await KubernetesCleanupCronJob.createCleanupCronJob(
|
||||
this.kubeClientBatchBeta,
|
||||
this.cleanupCronJobName,
|
||||
this.namespace,
|
||||
);
|
||||
}
|
||||
|
||||
async runBuildTask(
|
||||
|
|
@ -65,7 +71,19 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
|||
this.secretName = `build-credentials-${buildId}`;
|
||||
this.jobName = `unity-builder-job-${buildId}`;
|
||||
await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient);
|
||||
const jobSpec = this.getJobSpec(commands, image, mountdir, workingdir, environment);
|
||||
const jobSpec = KubernetesJobSpecFactory.getJobSpec(
|
||||
commands,
|
||||
image,
|
||||
mountdir,
|
||||
workingdir,
|
||||
environment,
|
||||
this.buildId,
|
||||
this.buildParameters,
|
||||
this.secretName,
|
||||
this.pvcName,
|
||||
this.jobName,
|
||||
k8s,
|
||||
);
|
||||
|
||||
//run
|
||||
core.info('Creating build job');
|
||||
|
|
@ -97,144 +115,6 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
|||
}
|
||||
}
|
||||
|
||||
getJobSpec(
|
||||
command: string[],
|
||||
image: string,
|
||||
mountdir: string,
|
||||
workingDirectory: string,
|
||||
environment: RemoteBuilderEnvironmentVariable[],
|
||||
) {
|
||||
environment.push(
|
||||
...[
|
||||
{
|
||||
name: 'GITHUB_SHA',
|
||||
value: this.buildId,
|
||||
},
|
||||
{
|
||||
name: 'GITHUB_WORKSPACE',
|
||||
value: '/data/repo',
|
||||
},
|
||||
{
|
||||
name: 'PROJECT_PATH',
|
||||
value: this.buildParameters.projectPath,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_PATH',
|
||||
value: this.buildParameters.buildPath,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_FILE',
|
||||
value: this.buildParameters.buildFile,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_NAME',
|
||||
value: this.buildParameters.buildName,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_METHOD',
|
||||
value: this.buildParameters.buildMethod,
|
||||
},
|
||||
{
|
||||
name: 'CUSTOM_PARAMETERS',
|
||||
value: this.buildParameters.customParameters,
|
||||
},
|
||||
{
|
||||
name: 'CHOWN_FILES_TO',
|
||||
value: this.buildParameters.chownFilesTo,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_TARGET',
|
||||
value: this.buildParameters.platform,
|
||||
},
|
||||
{
|
||||
name: 'ANDROID_VERSION_CODE',
|
||||
value: this.buildParameters.androidVersionCode.toString(),
|
||||
},
|
||||
{
|
||||
name: 'ANDROID_KEYSTORE_NAME',
|
||||
value: this.buildParameters.androidKeystoreName,
|
||||
},
|
||||
{
|
||||
name: 'ANDROID_KEYALIAS_NAME',
|
||||
value: this.buildParameters.androidKeyaliasName,
|
||||
},
|
||||
],
|
||||
);
|
||||
const job = new k8s.V1Job();
|
||||
job.apiVersion = 'batch/v1';
|
||||
job.kind = 'Job';
|
||||
job.metadata = {
|
||||
name: this.jobName,
|
||||
labels: {
|
||||
app: 'unity-builder',
|
||||
},
|
||||
};
|
||||
job.spec = {
|
||||
backoffLimit: 1,
|
||||
template: {
|
||||
spec: {
|
||||
volumes: [
|
||||
{
|
||||
name: 'build-mount',
|
||||
persistentVolumeClaim: {
|
||||
claimName: this.pvcName,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'credentials',
|
||||
secret: {
|
||||
secretName: this.secretName,
|
||||
},
|
||||
},
|
||||
],
|
||||
containers: [
|
||||
{
|
||||
name: 'main',
|
||||
image,
|
||||
command: ['/bin/sh'],
|
||||
args: ['-c', ...command],
|
||||
|
||||
workingDir: `/${workingDirectory}`,
|
||||
resources: {
|
||||
requests: {
|
||||
memory: this.buildParameters.remoteBuildMemory,
|
||||
cpu: this.buildParameters.remoteBuildCpu,
|
||||
},
|
||||
},
|
||||
env: environment,
|
||||
volumeMounts: [
|
||||
{
|
||||
name: 'build-mount',
|
||||
mountPath: `/${mountdir}`,
|
||||
},
|
||||
{
|
||||
name: 'credentials',
|
||||
mountPath: '/credentials',
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
lifecycle: {
|
||||
preStop: {
|
||||
exec: {
|
||||
command: [
|
||||
'bin/bash',
|
||||
'-c',
|
||||
`cd /data/builder/action/steps;
|
||||
chmod +x /return_license.sh;
|
||||
/return_license.sh;`,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
restartPolicy: 'Never',
|
||||
},
|
||||
},
|
||||
};
|
||||
return job;
|
||||
}
|
||||
|
||||
setPodNameAndContainerName(pod: k8s.V1Pod) {
|
||||
this.podName = pod.metadata?.name || '';
|
||||
this.containerName = pod.status?.containerStatuses?.[0].name || '';
|
||||
|
|
@ -270,6 +150,7 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
|||
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
|
||||
) {
|
||||
await this.kubeClient.deleteNamespacedPersistentVolumeClaim(this.pvcName, this.namespace);
|
||||
await KubernetesCleanupCronJob.cleanup(this.kubeClientBatchBeta, this.cleanupCronJobName, this.namespace);
|
||||
}
|
||||
}
|
||||
export default Kubernetes;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
import { BatchV1beta1Api, V1beta1CronJob } from '@kubernetes/client-node';
|
||||
import { Cron } from 'cron-converter';
|
||||
class KubernetesCleanupCronJob {
|
||||
static async cleanup(api: BatchV1beta1Api, name: string, namespace: string) {
|
||||
await api.deleteNamespacedCronJob('name', namespace);
|
||||
}
|
||||
static createCleanupCronJob(kubeClientBatch: BatchV1beta1Api, name: string, namespace: string) {
|
||||
const batchJob = new V1beta1CronJob();
|
||||
batchJob.kind = 'CronJob';
|
||||
batchJob.metadata = {
|
||||
name,
|
||||
labels: {
|
||||
app: 'unity-builder',
|
||||
},
|
||||
};
|
||||
const cronInstance = new Cron();
|
||||
const date = Date.now() + 1000 * 60 * 60;
|
||||
const spec = {
|
||||
containers: [
|
||||
{
|
||||
name: 'main',
|
||||
image: 'bitnami/kubectl',
|
||||
imagePullPolicy: '',
|
||||
command: ['/bin/sh'],
|
||||
args: [
|
||||
'-c',
|
||||
`
|
||||
echo "delete the kubernetes resources"
|
||||
kubectl get pods
|
||||
`,
|
||||
],
|
||||
restartPolicy: '',
|
||||
},
|
||||
],
|
||||
};
|
||||
batchJob.spec = {
|
||||
schedule: cronInstance.schedule(new Date(date)).toString(),
|
||||
jobTemplate: {
|
||||
spec: {
|
||||
template: { spec },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
kubeClientBatch.createNamespacedCronJob(namespace, batchJob);
|
||||
}
|
||||
}
|
||||
export default KubernetesCleanupCronJob;
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
import BuildParameters from '../build-parameters';
|
||||
import RemoteBuilderEnvironmentVariable from './remote-builder-environment-variable';
|
||||
|
||||
class KubernetesJobSpecFactory {
|
||||
static getJobSpec(
|
||||
command: string[],
|
||||
image: string,
|
||||
mountdir: string,
|
||||
workingDirectory: string,
|
||||
environment: RemoteBuilderEnvironmentVariable[],
|
||||
buildId: string,
|
||||
buildParameters: BuildParameters,
|
||||
secretName,
|
||||
pvcName,
|
||||
jobName,
|
||||
k8s,
|
||||
) {
|
||||
environment.push(
|
||||
...[
|
||||
{
|
||||
name: 'GITHUB_SHA',
|
||||
value: buildId,
|
||||
},
|
||||
{
|
||||
name: 'GITHUB_WORKSPACE',
|
||||
value: '/data/repo',
|
||||
},
|
||||
{
|
||||
name: 'PROJECT_PATH',
|
||||
value: buildParameters.projectPath,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_PATH',
|
||||
value: buildParameters.buildPath,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_FILE',
|
||||
value: buildParameters.buildFile,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_NAME',
|
||||
value: buildParameters.buildName,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_METHOD',
|
||||
value: buildParameters.buildMethod,
|
||||
},
|
||||
{
|
||||
name: 'CUSTOM_PARAMETERS',
|
||||
value: buildParameters.customParameters,
|
||||
},
|
||||
{
|
||||
name: 'CHOWN_FILES_TO',
|
||||
value: buildParameters.chownFilesTo,
|
||||
},
|
||||
{
|
||||
name: 'BUILD_TARGET',
|
||||
value: buildParameters.platform,
|
||||
},
|
||||
{
|
||||
name: 'ANDROID_VERSION_CODE',
|
||||
value: buildParameters.androidVersionCode.toString(),
|
||||
},
|
||||
{
|
||||
name: 'ANDROID_KEYSTORE_NAME',
|
||||
value: buildParameters.androidKeystoreName,
|
||||
},
|
||||
{
|
||||
name: 'ANDROID_KEYALIAS_NAME',
|
||||
value: buildParameters.androidKeyaliasName,
|
||||
},
|
||||
],
|
||||
);
|
||||
const job = new k8s.V1Job();
|
||||
job.apiVersion = 'batch/v1';
|
||||
job.kind = 'Job';
|
||||
job.metadata = {
|
||||
name: jobName,
|
||||
labels: {
|
||||
app: 'unity-builder',
|
||||
},
|
||||
};
|
||||
job.spec = {
|
||||
backoffLimit: 1,
|
||||
template: {
|
||||
spec: {
|
||||
volumes: [
|
||||
{
|
||||
name: 'build-mount',
|
||||
persistentVolumeClaim: {
|
||||
claimName: pvcName,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'credentials',
|
||||
secret: {
|
||||
secretName,
|
||||
},
|
||||
},
|
||||
],
|
||||
containers: [
|
||||
{
|
||||
name: 'main',
|
||||
image,
|
||||
command: ['/bin/sh'],
|
||||
args: ['-c', ...command],
|
||||
|
||||
workingDir: `/${workingDirectory}`,
|
||||
resources: {
|
||||
requests: {
|
||||
memory: buildParameters.remoteBuildMemory,
|
||||
cpu: buildParameters.remoteBuildCpu,
|
||||
},
|
||||
},
|
||||
env: environment,
|
||||
volumeMounts: [
|
||||
{
|
||||
name: 'build-mount',
|
||||
mountPath: `/${mountdir}`,
|
||||
},
|
||||
{
|
||||
name: 'credentials',
|
||||
mountPath: '/credentials',
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
lifecycle: {
|
||||
preStop: {
|
||||
exec: {
|
||||
command: [
|
||||
'bin/bash',
|
||||
'-c',
|
||||
`cd /data/builder/action/steps;
|
||||
chmod +x /return_license.sh;
|
||||
/return_license.sh;`,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
restartPolicy: 'Never',
|
||||
},
|
||||
},
|
||||
};
|
||||
return job;
|
||||
}
|
||||
}
|
||||
export default KubernetesJobSpecFactory;
|
||||
25
yarn.lock
25
yarn.lock
|
|
@ -1723,6 +1723,14 @@ cosmiconfig@^7.0.0:
|
|||
path-type "^4.0.0"
|
||||
yaml "^1.10.0"
|
||||
|
||||
cron-converter@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cron-converter/-/cron-converter-1.0.1.tgz#a7a13f49d69893523feef3c511280aab50f5e403"
|
||||
integrity sha512-2GpOtd4lGs5kOspHprRUbChyDXmA59cgqcVvIqZgqTSSOJ1tMW9rKoOEGyc+UXYZDUWyrPtf7dvrYyFCjmo/QA==
|
||||
dependencies:
|
||||
moment-timezone "~0.5"
|
||||
sprintf-js "~1"
|
||||
|
||||
cross-spawn@^6.0.0:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
|
|
@ -4024,6 +4032,18 @@ mkdirp@1.x, mkdirp@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
moment-timezone@~0.5:
|
||||
version "0.5.33"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.33.tgz#b252fd6bb57f341c9b59a5ab61a8e51a73bbd22c"
|
||||
integrity sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==
|
||||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
"moment@>= 2.9.0":
|
||||
version "2.29.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
|
|
@ -5073,6 +5093,11 @@ split-string@^3.0.1, split-string@^3.0.2:
|
|||
dependencies:
|
||||
extend-shallow "^3.0.0"
|
||||
|
||||
sprintf-js@~1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
|
||||
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
|
|
|
|||
Loading…
Reference in New Issue