From 81c796c74a4d45b11640df252206684c4bc3447a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Fran=C3=A7ois?= Date: Wed, 12 Feb 2025 10:28:08 +0100 Subject: [PATCH 1/6] :sparkles: Create a isItCompilling function --- assets/scripts/utils.js | 12 ++++++++++ package.json | 2 +- tests/utils.test.js | 49 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/utils.test.js diff --git a/assets/scripts/utils.js b/assets/scripts/utils.js index c2df60b..1a38621 100644 --- a/assets/scripts/utils.js +++ b/assets/scripts/utils.js @@ -128,3 +128,15 @@ export const logMessage = (errorMessage, caller = 'unknown', level = 'log') => { * @returns {Promise} */ export const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) + +/** + * + * @param {any} lastCommit + * @returns {boolean} + */ +export const isItStillCompiling = lastCommit => { + const ERROR_DELAY = 60 * 1000 + const currentTime = new Date().getTime() / 1000 + const deltaTime = currentTime - lastCommit.committer.timestamp + return deltaTime <= ERROR_DELAY +} diff --git a/package.json b/package.json index 89628ac..9d93ac7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "ts": "tsc && echo 'Tout va bien 🎉'", "dev": "rollup -c -w", "build": "rollup -c", - "test": "mocha tests/**/*.test.js", + "test": "mocha --recursive tests", "prepare": "husky install", "svelte-check": "svelte-check --tsconfig tsconfig.json" }, diff --git a/tests/utils.test.js b/tests/utils.test.js new file mode 100644 index 0000000..9d589f8 --- /dev/null +++ b/tests/utils.test.js @@ -0,0 +1,49 @@ +import './setup.js' +import { isItStillCompiling } from '../assets/scripts/utils.js' + +describe('Utils function', () => { + let now, clock + + beforeEach(() => { + now = new Date('2024-12-03 10:00') + clock = sinon.useFakeTimers(now.getTime()) + }) + + afterEach(() => { + clock.restore() + }) + + describe('#isItStillCompiling', () => { + it('returns true when just commited', () => { + const lastCommit = { + committer: { + timestamp: now.getTime() / 1000, + }, + } + + expect(isItStillCompiling(lastCommit)).to.be.true + }) + + it('returns true when commited since less than DELAY', () => { + const commitDatetime = new Date('2024-12-03 10:29') + const lastCommit = { + committer: { + timestamp: commitDatetime.getTime() / 1000, + }, + } + + expect(isItStillCompiling(lastCommit)).to.be.true + }) + + it('returns false when commited since more than DELAY', () => { + const commitDatetime = new Date('2024-12-02 15:30') + const lastCommit = { + committer: { + timestamp: commitDatetime.getTime() / 1000, + }, + } + + expect(isItStillCompiling(lastCommit)).to.be.false + }) + }) +}) From 00365a0c699850ab0889b21906c619edc9419bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Fran=C3=A7ois?= Date: Wed, 12 Feb 2025 11:06:45 +0100 Subject: [PATCH 2/6] wip --- assets/scripts/buildStatus.js | 19 ++++++++----------- assets/scripts/utils.js | 1 + 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/assets/scripts/buildStatus.js b/assets/scripts/buildStatus.js index 47a4fd3..71e4eeb 100644 --- a/assets/scripts/buildStatus.js +++ b/assets/scripts/buildStatus.js @@ -2,6 +2,7 @@ import GitAgent from './GitAgent.js' import { getOAuthServiceAPI } from './oauth-services-api/index.js' +import { isItStillCompiling } from './utils.js' /** * @@ -68,9 +69,6 @@ export default function (scribouilliGitRepo, gitAgent) { return buildStatusObject } -/** Delay (in seconds) after which a non-updated website is assumed to have failed to build. */ -const ERROR_DELAY = 60 - /** * mimoza includes the hash of the latest built commit in a comment in the HTML * of each page. We use that to know which version is currently online, and @@ -90,9 +88,10 @@ async function getBuildStatus(currentRepository, gitAgent) { const url = new URL(req.url) if (req.redirected && url.hostname.endsWith('projects.gitlab.io')) { - throw new Error( - 'Redirection vers la page de login GitLab: le site est privĂ©', - ) + // If the website is a "private" GitLab repo, we will receive a redirection to + // GitLab to login, which will fail because of CORS. In case it doesn't fail, + // the Error we throw above should still catch this redirection. + return 'not_public' } html = await req.text() @@ -125,12 +124,10 @@ async function getBuildStatus(currentRepository, gitAgent) { if (hash === lastCommit.oid.slice(0, 7)) { return 'success' } else { - const currentTime = new Date().getTime() / 1000 - const deltaTime = currentTime - lastCommit.committer.timestamp - if (deltaTime > ERROR_DELAY) { - return 'error' - } else { + if (isItStillCompiling(lastCommit)) { return 'in_progress' + } else { + return 'error' } } } diff --git a/assets/scripts/utils.js b/assets/scripts/utils.js index 1a38621..3a36420 100644 --- a/assets/scripts/utils.js +++ b/assets/scripts/utils.js @@ -135,6 +135,7 @@ export const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) * @returns {boolean} */ export const isItStillCompiling = lastCommit => { + // Delay (in seconds) after which a non-updated website is assumed to have failed to build. const ERROR_DELAY = 60 * 1000 const currentTime = new Date().getTime() / 1000 const deltaTime = currentTime - lastCommit.committer.timestamp From 96f5b6d0dc88089172936738605511ecdb0e8dcb Mon Sep 17 00:00:00 2001 From: Fanny Cheung Date: Wed, 12 Feb 2025 14:44:18 +0100 Subject: [PATCH 3/6] Ajoute un type pour les objets commit --- assets/scripts/types/git.js | 20 ++++++++++++++++++++ assets/scripts/utils.js | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/assets/scripts/types/git.js b/assets/scripts/types/git.js index 5fa535d..3108c93 100644 --- a/assets/scripts/types/git.js +++ b/assets/scripts/types/git.js @@ -67,3 +67,23 @@ * @property {Object} owner * @property {string} owner.login */ + +/** + * A git commit object. + * + * @typedef {Object} CommitObject + * @property {string} message Commit message + * @property {string} tree SHA-1 object id of corresponding file tree + * @property {string[]} parent an array of zero or more SHA-1 object ids + * @property {Object} author + * @property {string} author.name The author's name + * @property {string} author.email The author's email + * @property {number} author.timestamp UTC Unix timestamp in seconds + * @property {number} author.timezoneOffset Timezone difference from UTC in minutes + * @property {Object} committer + * @property {string} committer.name The committer's name + * @property {string} committer.email The committer's email + * @property {number} committer.timestamp UTC Unix timestamp in seconds + * @property {number} committer.timezoneOffset Timezone difference from UTC in minutes + * @property {string} [gpgsig] PGP signature (if present) + */ diff --git a/assets/scripts/utils.js b/assets/scripts/utils.js index 3a36420..5222c73 100644 --- a/assets/scripts/utils.js +++ b/assets/scripts/utils.js @@ -131,7 +131,7 @@ export const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) /** * - * @param {any} lastCommit + * @param {CommitObject} lastCommit * @returns {boolean} */ export const isItStillCompiling = lastCommit => { From 6bb2e5dfb069992b5eb6125dada616c1f897e90a Mon Sep 17 00:00:00 2001 From: Fanny Cheung Date: Wed, 12 Feb 2025 17:05:52 +0100 Subject: [PATCH 4/6] =?UTF-8?q?Retire=20la=20gestion=20du=20cas=20des=20si?= =?UTF-8?q?tes=20priv=C3=A9s=20et=20g=C3=A8re=20le=20souci=20des=20comptes?= =?UTF-8?q?=20non-v=C3=A9rifi=C3=A9s=20sur=20GitLab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/scripts/buildStatus.js | 44 +++++++++++++------------ assets/scripts/components/Header.svelte | 25 -------------- assets/scripts/types/git.js | 3 +- 3 files changed, 24 insertions(+), 48 deletions(-) diff --git a/assets/scripts/buildStatus.js b/assets/scripts/buildStatus.js index 71e4eeb..220cf67 100644 --- a/assets/scripts/buildStatus.js +++ b/assets/scripts/buildStatus.js @@ -45,7 +45,7 @@ export default function (scribouilliGitRepo, gitAgent) { reaction(repoStatus) } - if (repoStatus === 'in_progress' || repoStatus === 'not_public') { + if (repoStatus === 'in_progress') { scheduleCheck() } }) @@ -80,31 +80,33 @@ export default function (scribouilliGitRepo, gitAgent) { */ async function getBuildStatus(currentRepository, gitAgent) { const publishedWebsiteURL = await currentRepository.publishedWebsiteURL + const lastCommit = await gitAgent.currentCommit() + let html - try { - const req = await fetch(publishedWebsiteURL, { - cache: 'no-store', - }) - - const url = new URL(req.url) - if (req.redirected && url.hostname.endsWith('projects.gitlab.io')) { - // If the website is a "private" GitLab repo, we will receive a redirection to - // GitLab to login, which will fail because of CORS. In case it doesn't fail, - // the Error we throw above should still catch this redirection. - return 'not_public' - } - html = await req.text() - } catch { - // If the website is a "private" GitLab repo, we will receive a redirection to - // GitLab to login, which will fail because of CORS. In case it doesn't fail, - // the Error we throw above should still catch this redirection. - return 'not_public' + const response = await fetch(publishedWebsiteURL, { + cache: 'no-store', + }) + + const url = new URL(response.url) + + if (response.redirected && url.hostname.endsWith('projects.gitlab.io')) { + // We handle the case where GitLab redirects to the login page + // because the account is not verified. + return 'needs_account_verification' } - const dom = new DOMParser().parseFromString(html, 'text/html') + if (!response.ok && isItStillCompiling(lastCommit)) { + return 'in_progress' + } - const lastCommit = await gitAgent.currentCommit() + if (!response.ok) { + return 'error' + } + + html = await response.text() + + const dom = new DOMParser().parseFromString(html, 'text/html') for (const node of dom.documentElement.childNodes) { if (node.nodeType === dom.COMMENT_NODE) { diff --git a/assets/scripts/components/Header.svelte b/assets/scripts/components/Header.svelte index fdd8abd..25f08f9 100644 --- a/assets/scripts/components/Header.svelte +++ b/assets/scripts/components/Header.svelte @@ -26,10 +26,6 @@ }) } - /** @type {boolean} */ - let notPublic - $: notPublic = status === 'not_public' - $: buildStatusClass = buildStatus ? `build-${status}` : undefined /** @type {Promise | undefined } */ @@ -67,11 +63,6 @@ let resolutionURL; $: resolutionURL = makeResolutionDesynchronisationURL(account || '', repoName || '') - /** @type {string | undefined} */ - let gitlabSettingsUrl - $: gitlabSettingsUrl = currentRepository?.publicRepositoryURL - ? `${currentRepository.publicRepositoryURL}/edit#js-shared-permissions` - : undefined
@@ -156,22 +147,6 @@ {/if} - -{#if notPublic} -
-

⚠ Votre site n'est pas (encore) public.

- -

Pour le rendre public, il vous faut :

- -
    -
  1. Aller sur la page "ParamÚtres / Général / Visibilité, fonctionnalités du projet, autorisations" de Gitlab
  2. -
  3. Trouver la sous-section "Pages"
  4. -
  5. Choisir, au lieu de "Only project members", "Everyone with access" dans la liste déroulante
  6. -
  7. Enregistrer le changement en appuyant sur le bouton bleu "Save changes"
  8. -
-
-{/if} -