From 99ef3c2a1783b66e7b2691d3439d1a6464b3b216 Mon Sep 17 00:00:00 2001 From: SuperDelphi Date: Wed, 29 May 2024 14:57:41 +0200 Subject: [PATCH 01/11] Added plugin --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cd182f99..24f52c37 100644 --- a/package.json +++ b/package.json @@ -108,9 +108,8 @@ "@silexlabs/grapesjs-loading": "1.0.9", "@silexlabs/grapesjs-notifications": "^0.0.8", "@silexlabs/grapesjs-storage-rate-limit": "^1.0.8", - "@silexlabs/grapesjs-symbols": "1.0.41", + "@silexlabs/grapesjs-symbols": "1.0.40", "@silexlabs/grapesjs-ui-suggest-classes": "1.0.23", - "@silexlabs/grapesjs-keymaps-dialog": "^1.0.15", "@silexlabs/silex-plugins": "1.0.10", "@types/archiver": "^6.0.2", "adm-zip": "0.5.12", @@ -139,7 +138,7 @@ "html-minifier": "^4.0.0", "lit-html": "3.1.2", "mkdirp": "3.0.1", - "node_modules-path": "2.0.8", + "node_modules-path": "2.0.7", "node-fetch": "2.6.9", "normalize.css": "8.0.1", "object-path": "0.11.8", From 6dead66d067124a97e6800017d0b0ab66e2c8e9d Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:24:47 +0200 Subject: [PATCH 02/11] Update package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 24f52c37..5273b63a 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "@silexlabs/grapesjs-storage-rate-limit": "^1.0.8", "@silexlabs/grapesjs-symbols": "1.0.40", "@silexlabs/grapesjs-ui-suggest-classes": "1.0.23", + "@silexlabs/grapesjs-keymaps-dialog": "^1.0.0", "@silexlabs/silex-plugins": "1.0.10", "@types/archiver": "^6.0.2", "adm-zip": "0.5.12", From 58df1ce9694280fc7f1103f57e213274d4e94de6 Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 01:41:18 +0200 Subject: [PATCH 03/11] The publication dialog now displays a message to suggest the user to verify their GitLab account when needed + Loading bar visual improvement --- src/css/grapesjs-plugins.scss | 35 +++++++++++++++++++ src/ts/plugins/server/GitlabConnector.ts | 11 ++++-- .../plugins/server/GitlabHostingConnector.ts | 20 ++++++++++- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/css/grapesjs-plugins.scss b/src/css/grapesjs-plugins.scss index cfbd161a..810436e2 100644 --- a/src/css/grapesjs-plugins.scss +++ b/src/css/grapesjs-plugins.scss @@ -59,7 +59,42 @@ } // publication-ui +@keyframes pub-blink { + from { + opacity: 0.25; + } + to { + opacity: 1; + } +} + #publish-dialog { + .notice { + margin: 10px 0; + background-color: rgba(255, 166, 0, 0.2); + border-radius: 5px; + padding: 10px; + } + + progress { + width: 100%; + border-radius: 50px; + border: none; + height: 5px; + animation: pub-blink 0.33s infinite alternate; + background-color: $tertiaryColor; + } + + progress::-webkit-progress-bar { + border-radius: 50px; + background-color: $tertiaryColor; + } + + progress::-moz-progress-bar { + border-radius: 50px; + background-color: $tertiaryColor; + } + header { display: flex; align-items: center; diff --git a/src/ts/plugins/server/GitlabConnector.ts b/src/ts/plugins/server/GitlabConnector.ts index fb9f6ace..7703eebd 100644 --- a/src/ts/plugins/server/GitlabConnector.ts +++ b/src/ts/plugins/server/GitlabConnector.ts @@ -210,6 +210,11 @@ export default class GitlabConnector implements StorageConnector { return encodeURIComponent(join(this.options.assetsFolder, path)) } + isUsingOfficialInstance(): boolean { + const gitlabDomainRegexp = /(^|\b)(gitlab\.com)($|\b)/ + return gitlabDomainRegexp.test(this.options.domain) + } + async createFile(session: GitlabSession, websiteId: WebsiteId, path: string, content: string, isBase64 = false): Promise { // Remove leading slash const safePath = path.replace(/^\//, '') @@ -292,7 +297,7 @@ export default class GitlabConnector implements StorageConnector { const headers = { 'Content-Type': 'application/json', } - if(method === 'GET' && body) { + if (method === 'GET' && body) { console.error('Gitlab API error (4) - GET request with body', {url, method, body, params}) } // With or without body @@ -311,9 +316,9 @@ export default class GitlabConnector implements StorageConnector { throw new ApiError(`Gitlab API error (0): ${e.message} ${e.code} ${e.name} ${e.type}`, 500) } let json: { message: string, error: string } | any - // Handle the case when the server returns an non-JSON response (e.g. 400 Bad Request) + // Handle the case when the server returns a non-JSON response (e.g. 400 Bad Request) const text = await response.text() - if(!response.ok) { + if (!response.ok) { if (text.includes('A file with this name doesn\'t exist')) { throw new ApiError('Gitlab API error (5): Not Found', 404) } else if (response.status === 401 && this.getSessionToken(session).token?.refresh_token) { diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index 26e21219..7702c2ce 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -101,6 +101,23 @@ export default class GitlabHostingConnector extends GitlabConnector implements H job.message = 'Getting the deployment logs URL...' job.logs[0].push(job.message) const gitlabJobLogsUrl = await this.getGitlabJobLogsUrl(session, websiteId, adminUrl) + + // Because of the GitLab policy, this can be undefined (and we suggest the user to verify their account) + if (!gitlabJobLogsUrl) { + let errorMessage = 'Could not retrieve the deployment logs URL.' + + if (this.isUsingOfficialInstance()) { + const verifyURL = 'https://gitlab.com/-/identity_verification' + errorMessage += + `
+ If your GitLab account is recent, you may need to verify it here + in order to be able to use pipelines (this is GitLab's policy, not Silex's). +
` + } + + throw new Error(errorMessage) + } + job.logs[0].push(`Deployment logs URL: ${gitlabJobLogsUrl}`) const message = `

Your website is now live here.

@@ -146,8 +163,9 @@ export default class GitlabHostingConnector extends GitlabConnector implements H return `${projectUrl}/pages` } - async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, projectUrl: string): Promise { + async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, projectUrl: string): Promise { const jobs = await this.callApi(session, `api/v4/projects/${websiteId}/jobs`, 'GET') + if (!jobs.length) return undefined return `${projectUrl}/-/jobs/${jobs[0].id}` } From c75c7eabab90875ed49561122031809a8d853be8 Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 01:49:19 +0200 Subject: [PATCH 04/11] Update grapesjs-plugins.scss --- src/css/grapesjs-plugins.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/css/grapesjs-plugins.scss b/src/css/grapesjs-plugins.scss index 810436e2..329fff56 100644 --- a/src/css/grapesjs-plugins.scss +++ b/src/css/grapesjs-plugins.scss @@ -86,12 +86,10 @@ } progress::-webkit-progress-bar { - border-radius: 50px; background-color: $tertiaryColor; } progress::-moz-progress-bar { - border-radius: 50px; background-color: $tertiaryColor; } From b3b4ab3a75e25c1689d64aee1e3b68e745da8ad8 Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:34:58 +0200 Subject: [PATCH 05/11] Update GitlabHostingConnector.ts --- src/ts/plugins/server/GitlabHostingConnector.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index 7702c2ce..b6228c62 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -102,7 +102,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H job.logs[0].push(job.message) const gitlabJobLogsUrl = await this.getGitlabJobLogsUrl(session, websiteId, adminUrl) - // Because of the GitLab policy, this can be undefined (and we suggest the user to verify their account) + // Because of the GitLab policy, this can be null (and we suggest the user to verify their account) if (!gitlabJobLogsUrl) { let errorMessage = 'Could not retrieve the deployment logs URL.' @@ -163,9 +163,9 @@ export default class GitlabHostingConnector extends GitlabConnector implements H return `${projectUrl}/pages` } - async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, projectUrl: string): Promise { + async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, projectUrl: string): Promise { const jobs = await this.callApi(session, `api/v4/projects/${websiteId}/jobs`, 'GET') - if (!jobs.length) return undefined + if (!jobs.length) return null return `${projectUrl}/-/jobs/${jobs[0].id}` } From c56092500e0deeda32a5fd87f0d5733298593235 Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:41:25 +0200 Subject: [PATCH 06/11] Added a target=_blank on the link --- src/ts/plugins/server/GitlabHostingConnector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index b6228c62..d67d4cf5 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -110,7 +110,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H const verifyURL = 'https://gitlab.com/-/identity_verification' errorMessage += `
- If your GitLab account is recent, you may need to verify it here + If your GitLab account is recent, you may need to verify it here in order to be able to use pipelines (this is GitLab's policy, not Silex's).
` } From 4accdaebb8cb923f8da218f7ecf1d280924b1c7b Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:43:32 +0200 Subject: [PATCH 07/11] Update package.json --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5273b63a..cd182f99 100644 --- a/package.json +++ b/package.json @@ -108,9 +108,9 @@ "@silexlabs/grapesjs-loading": "1.0.9", "@silexlabs/grapesjs-notifications": "^0.0.8", "@silexlabs/grapesjs-storage-rate-limit": "^1.0.8", - "@silexlabs/grapesjs-symbols": "1.0.40", + "@silexlabs/grapesjs-symbols": "1.0.41", "@silexlabs/grapesjs-ui-suggest-classes": "1.0.23", - "@silexlabs/grapesjs-keymaps-dialog": "^1.0.0", + "@silexlabs/grapesjs-keymaps-dialog": "^1.0.15", "@silexlabs/silex-plugins": "1.0.10", "@types/archiver": "^6.0.2", "adm-zip": "0.5.12", @@ -139,7 +139,7 @@ "html-minifier": "^4.0.0", "lit-html": "3.1.2", "mkdirp": "3.0.1", - "node_modules-path": "2.0.7", + "node_modules-path": "2.0.8", "node-fetch": "2.6.9", "normalize.css": "8.0.1", "object-path": "0.11.8", From d7eac525c09aa79c0f402a1d6171074311535c24 Mon Sep 17 00:00:00 2001 From: oliviermgx <73127173+oliviermgx@users.noreply.github.com> Date: Wed, 19 Jun 2024 08:07:58 +0200 Subject: [PATCH 08/11] Bug job id return in gitlab host connector (#1604) * gitlab hosting connector with good current job id return * gitlab hosting connector with good current job id return 2 * gitlab hosting connector with good current job id return v3 * with setTimout problem corrected * with setTimout problem corrected 2 * with setTimout problem corrected 3 * with setTimout problem corrected 3 * with setTimout problem corrected 3 * with setTimout problem corrected 4 * with setTimout problem corrected 4 * with setTimout problem corrected 5 * with setTimout problem corrected 5 * with setTimout problem corrected 6 * with timer in variables --------- Co-authored-by: Ubuntu --- src/ts/plugins/server/GitlabConnector.ts | 3 +- .../plugins/server/GitlabHostingConnector.ts | 39 ++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/ts/plugins/server/GitlabConnector.ts b/src/ts/plugins/server/GitlabConnector.ts index 7703eebd..8f12c14d 100644 --- a/src/ts/plugins/server/GitlabConnector.ts +++ b/src/ts/plugins/server/GitlabConnector.ts @@ -39,6 +39,7 @@ export interface GitlabOptions { repoPrefix: string scope: string domain: string + timeOut: number } export interface GitlabToken { @@ -201,7 +202,7 @@ export default class GitlabConnector implements StorageConnector { if(!this.options.clientId) throw new Error('Missing Gitlab client ID') if(!this.options.clientSecret) throw new Error('Missing Gitlab client secret') if(!this.options.domain) throw new Error('Missing Gitlab domain') - + if(!this.options.timeOut) this.options.timeOut = 15000 /* default value */ } // ** diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index d67d4cf5..0e9399dd 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -26,9 +26,10 @@ import GitlabConnector, { GitlabOptions, GitlabSession} from './GitlabConnector' import { HostingConnector, ConnectorFile } from '../../server/connectors/connectors' import { ConnectorType, WebsiteId, JobData, JobStatus, PublicationJobData } from '../../types' import { JobManager } from '../../server/jobs' -import { join } from 'path' import { ServerConfig } from '../../server/config' -import { stat } from 'fs' +import { setTimeout } from 'timers/promises' + +const waitTimeOut = 5000 /* for wait loop in job pages getting */ export default class GitlabHostingConnector extends GitlabConnector implements HostingConnector { @@ -80,8 +81,8 @@ export default class GitlabHostingConnector extends GitlabConnector implements H // Update the job status if(status === JobStatus.SUCCESS) { /* Squash and tag the commits */ - const succes = await this.createTag(session, websiteId, job, { startJob, jobSuccess, jobError }) - if(!succes) { + const successTag = await this.createTag(session, websiteId, job, { startJob, jobSuccess, jobError }) + if(!successTag) { // jobError will have been called in createTag return } @@ -100,7 +101,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H job.logs[0].push(`Page URL: ${pageUrl}`) job.message = 'Getting the deployment logs URL...' job.logs[0].push(job.message) - const gitlabJobLogsUrl = await this.getGitlabJobLogsUrl(session, websiteId, adminUrl) + const gitlabJobLogsUrl = await this.getGitlabJobLogsUrl(session, websiteId, job, { startJob, jobSuccess, jobError }, adminUrl, successTag) // Because of the GitLab policy, this can be null (and we suggest the user to verify their account) if (!gitlabJobLogsUrl) { @@ -163,13 +164,24 @@ export default class GitlabHostingConnector extends GitlabConnector implements H return `${projectUrl}/pages` } - async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, projectUrl: string): Promise { - const jobs = await this.callApi(session, `api/v4/projects/${websiteId}/jobs`, 'GET') - if (!jobs.length) return null - return `${projectUrl}/-/jobs/${jobs[0].id}` + // waiting for the job corresponding to the current tag + async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, job: PublicationJobData, { startJob, jobSuccess, jobError }: JobManager, projectUrl: string, tag): Promise { + const t0 = Date.now() + do { + const jobs = await this.callApi(session, `api/v4/projects/${websiteId}/jobs`, 'GET') + if (!jobs.length) return null + if (jobs[0].ref === tag) {return `${projectUrl}/-/jobs/${jobs[0].id}`} + await setTimeout(waitTimeOut) + } while ((Date.now() - t0) < this.options.timeOut) + + // failed in timelaps allowed (avoiding infinite loop) + jobError(job.jobId, 'Failed to get job id') + job.message = 'Unable to get job id' + job.logs[0].push(job.message) + return `${projectUrl}/-/jobs/` } - async createTag(session: GitlabSession, websiteId: WebsiteId, job: JobData, { startJob, jobSuccess, jobError }: JobManager): Promise { + async createTag(session: GitlabSession, websiteId: WebsiteId, job: JobData, { startJob, jobSuccess, jobError }: JobManager): Promise { const projectId = websiteId // Assuming websiteId corresponds to GitLab project ID // Fetch the latest tag and determine the new tag @@ -184,7 +196,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } catch (error) { console.error('Error during fetching latest tag:', error.message) jobError(job.jobId, `Failed to fetch latest tag: ${error.message}`) - return false + return null } // Create a new tag @@ -198,9 +210,10 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } catch (error) { console.error('Error during creating new tag:', error.message) jobError(job.jobId, `Failed to create new tag: ${error.message}`) - return false + return null } - return true + // return new tag + return newTag } } From 036921bf685f9a0fe0b1b9f6623c602c3d10d567 Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 01:41:18 +0200 Subject: [PATCH 09/11] The publication dialog now displays a message to suggest the user to verify their GitLab account when needed + Loading bar visual improvement --- src/ts/plugins/server/GitlabHostingConnector.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index 0e9399dd..5fe90c85 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -165,7 +165,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } // waiting for the job corresponding to the current tag - async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, job: PublicationJobData, { startJob, jobSuccess, jobError }: JobManager, projectUrl: string, tag): Promise { + async getGitlabJobLogsUrl(session: GitlabSession, websiteId: WebsiteId, job: PublicationJobData, { startJob, jobSuccess, jobError }: JobManager, projectUrl: string, tag): Promise { const t0 = Date.now() do { const jobs = await this.callApi(session, `api/v4/projects/${websiteId}/jobs`, 'GET') @@ -196,7 +196,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } catch (error) { console.error('Error during fetching latest tag:', error.message) jobError(job.jobId, `Failed to fetch latest tag: ${error.message}`) - return null + return false } // Create a new tag @@ -210,10 +210,9 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } catch (error) { console.error('Error during creating new tag:', error.message) jobError(job.jobId, `Failed to create new tag: ${error.message}`) - return null + return false } - // return new tag - return newTag + return true } } From c316f26f193e6f8134b6f5cbd0d53d406d8d4ee9 Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:56:02 +0200 Subject: [PATCH 10/11] Merged changes --- src/ts/plugins/server/GitlabHostingConnector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index 5fe90c85..0735cd0e 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -131,7 +131,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H console.error('Error during getting the website URLs:', error.message) jobError(job.jobId, `Failed to get the website URLs: ${error.message}`) } - } else if(status === JobStatus.ERROR) { + } else if (status === JobStatus.ERROR) { job.errors[0].push(message) jobError(job.jobId, message) } else { From c5f16f9a1d195879ac20d81cbef249b3ad94b84d Mon Sep 17 00:00:00 2001 From: SuperDelphi <44942598+SuperDelphi@users.noreply.github.com> Date: Wed, 19 Jun 2024 12:09:57 +0200 Subject: [PATCH 11/11] Fixed bad merge --- src/ts/plugins/server/GitlabHostingConnector.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ts/plugins/server/GitlabHostingConnector.ts b/src/ts/plugins/server/GitlabHostingConnector.ts index 0735cd0e..9c1e64d7 100644 --- a/src/ts/plugins/server/GitlabHostingConnector.ts +++ b/src/ts/plugins/server/GitlabHostingConnector.ts @@ -196,7 +196,7 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } catch (error) { console.error('Error during fetching latest tag:', error.message) jobError(job.jobId, `Failed to fetch latest tag: ${error.message}`) - return false + return null } // Create a new tag @@ -210,9 +210,9 @@ export default class GitlabHostingConnector extends GitlabConnector implements H } catch (error) { console.error('Error during creating new tag:', error.message) jobError(job.jobId, `Failed to create new tag: ${error.message}`) - return false + return null } - return true + return newTag } }