diff --git a/assets/scripts/buildStatus.js b/assets/scripts/buildStatus.js index 47a4fd3..d5d68fe 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' /** * @@ -44,7 +45,10 @@ export default function (scribouilliGitRepo, gitAgent) { reaction(repoStatus) } - if (repoStatus === 'in_progress' || repoStatus === 'not_public') { + if ( + repoStatus === 'in_progress' || + repoStatus === 'needs_account_verification' + ) { scheduleCheck() } }) @@ -68,9 +72,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 @@ -82,30 +83,33 @@ const ERROR_DELAY = 60 */ 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')) { - throw new Error( - 'Redirection vers la page de login GitLab: le site est privé', - ) - } - 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) { @@ -125,12 +129,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/components/Header.svelte b/assets/scripts/components/Header.svelte index fdd8abd..0ddbb1f 100644 --- a/assets/scripts/components/Header.svelte +++ b/assets/scripts/components/Header.svelte @@ -26,9 +26,9 @@ }) } - /** @type {boolean} */ - let notPublic - $: notPublic = status === 'not_public' + /** @type {boolean}*/ + let needsAccountVerification + $: needsAccountVerification = status === 'needs_account_verification' $: buildStatusClass = buildStatus ? `build-${status}` : undefined @@ -67,11 +67,6 @@ let resolutionURL; $: resolutionURL = makeResolutionDesynchronisationURL(account || '', repoName || '') - /** @type {string | undefined} */ - let gitlabSettingsUrl - $: gitlabSettingsUrl = currentRepository?.publicRepositoryURL - ? `${currentRepository.publicRepositoryURL}/edit#js-shared-permissions` - : undefined
@@ -156,19 +151,19 @@ {/if} - -{#if notPublic} +{#if needsAccountVerification}
-

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

+

⚠️ Attention..

-

Pour le rendre public, il vous faut :

+

+ Votre site ne peut pas être publié car GitLab exige de vérifier votre identité avec un n° de téléphone (ou un n° de carte bleue). +

-
    -
  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. -
+

+ + Vérifier mon identité + +

{/if} diff --git a/assets/scripts/types/git.js b/assets/scripts/types/git.js index 5fa535d..ac4d1d9 100644 --- a/assets/scripts/types/git.js +++ b/assets/scripts/types/git.js @@ -16,8 +16,7 @@ */ /** - * @description On pense que ça correspond au build status de GitHub? - * @typedef {"in_progress" | "success" | "error" | "not_public"} BuildStatus + * @typedef {"in_progress" | "success" | "error" | "needs_account_verification" } BuildStatus */ /** @@ -67,3 +66,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 c2df60b..5222c73 100644 --- a/assets/scripts/utils.js +++ b/assets/scripts/utils.js @@ -128,3 +128,16 @@ export const logMessage = (errorMessage, caller = 'unknown', level = 'log') => { * @returns {Promise} */ export const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) + +/** + * + * @param {CommitObject} lastCommit + * @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 + 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 + }) + }) +})