Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions .github/pages/builds.html
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,11 @@ <h2>Save and apply</h2>
const r = repo.includes("/") ? ` -R ${repo}` : "";
return `gh workflow run reconfigure.yml${r} \\\n -f builds="${buildsInput()}"`;
}
function workflowUrl() { return repo.includes("/") ? "https://github.com/" + repo + "/actions/workflows/reconfigure.yml" : "https://github.com/actions/workflows/reconfigure.yml"; }
function workflowUrl() {
const parts = repo.trim().split("/").filter(Boolean);
const repoPath = parts.length === 2 ? parts.map(encodeURIComponent).join("/") : "";
return repoPath ? "https://github.com/" + repoPath + "/actions/workflows/reconfigure.yml" : "https://github.com/actions/workflows/reconfigure.yml";
}
function update() {
$("ghCmd").textContent = genGhCmd();
const wf = $("wfLink"); if (wf) wf.href = workflowUrl();
Expand All @@ -379,9 +383,19 @@ <h2>Save and apply</h2>
qp.set("actions", "write");
return "https://github.com/settings/personal-access-tokens/new?" + qp.toString();
}
function setApplyStatus(html, kind) {
function setApplyStatus(message, kind, workflowLink) {
const st = $("applyStatus"); if (!st) return;
st.innerHTML = html || ""; st.className = "status" + (kind ? " " + kind : "");
st.replaceChildren(message || "");
if (workflowLink) {
const link = document.createElement("a");
link.href = workflowLink;
link.target = "_blank";
link.rel = "noopener";
link.textContent = "View runs";
st.appendChild(link);
st.appendChild(document.createTextNode("."));
}
st.className = "status" + (kind ? " " + kind : "");
}
function showTokenPanel(msg) {
const p = $("tokPanel"); if (!p) return;
Expand All @@ -407,7 +421,7 @@ <h2>Save and apply</h2>
if (btn) { btn.disabled = false; btn.textContent = "Save and apply"; }
if (r.status === 204) {
hideTokenPanel();
setApplyStatus("Queued Reconfigure. It will open a pull request when the settings file is updated. <a href=\"" + workflowUrl() + "\" target=\"_blank\" rel=\"noopener\">View runs</a>.", "ok");
setApplyStatus("Queued Reconfigure. It will open a pull request when the settings file is updated. ", "ok", workflowUrl());
return;
}
if (r.status === 401) { try { localStorage.removeItem(TOK_KEY); } catch (_) {} showTokenPanel("That token was rejected. Paste a valid fine-grained token with <strong>Actions: Read and write</strong> for this repository."); setApplyStatus("Token rejected (401).", "err"); return; }
Expand All @@ -416,7 +430,7 @@ <h2>Save and apply</h2>
setApplyStatus("Dispatch failed (HTTP " + r.status + ").", "err");
} catch (e) {
if (btn) { btn.disabled = false; btn.textContent = "Save and apply"; }
setApplyStatus("Network error: " + escapeHtml(String(e && e.message || e)), "err");
setApplyStatus("Network error: " + String(e && e.message || e), "err");
}
}

Expand Down
22 changes: 16 additions & 6 deletions .github/pages/configure.html
Original file line number Diff line number Diff line change
Expand Up @@ -1243,8 +1243,9 @@ <h2>Save and apply</h2>
}

function workflowUrl() {
const repo = $("repo").value.trim();
return repo.includes("/") ? "https://github.com/" + repo + "/actions/workflows/reconfigure.yml" : "https://github.com/actions/workflows/reconfigure.yml";
const parts = $("repo").value.trim().split("/").filter(Boolean);
const repoPath = parts.length === 2 ? parts.map(encodeURIComponent).join("/") : "";
return repoPath ? "https://github.com/" + repoPath + "/actions/workflows/reconfigure.yml" : "https://github.com/actions/workflows/reconfigure.yml";
}
function token() { try { return localStorage.getItem(TOK_KEY) || ""; } catch (_) { return ""; } }
function tokenUrl() {
Expand All @@ -1257,9 +1258,18 @@ <h2>Save and apply</h2>
qp.set("actions", "write");
return "https://github.com/settings/personal-access-tokens/new?" + qp.toString();
}
function setApplyStatus(html, kind) {
function setApplyStatus(message, kind, workflowLink) {
const st = $("applyStatus"); if (!st) return;
st.innerHTML = html || "";
st.replaceChildren(message || "");
if (workflowLink) {
const link = document.createElement("a");
link.href = workflowLink;
link.target = "_blank";
link.rel = "noopener";
link.textContent = "View runs";
st.appendChild(link);
st.appendChild(document.createTextNode("."));
}
st.className = "status" + (kind ? " " + kind : "");
}
function showTokenPanel(msg) {
Expand Down Expand Up @@ -1301,7 +1311,7 @@ <h2>Save and apply</h2>
if (btn) { btn.disabled = false; btn.textContent = "Save and apply"; }
if (r.status === 204) {
hideTokenPanel();
setApplyStatus("Queued Reconfigure. It will open a pull request when the settings files are updated. <a href=\"" + workflowUrl() + "\" target=\"_blank\" rel=\"noopener\">View runs</a>.", "ok");
setApplyStatus("Queued Reconfigure. It will open a pull request when the settings files are updated. ", "ok", workflowUrl());
return;
}
if (r.status === 401) { try { localStorage.removeItem(TOK_KEY); } catch (_) {} showTokenPanel("That token was rejected. Paste a valid fine-grained token with <strong>Actions: Read and write</strong> for this repository."); setApplyStatus("Token rejected (401).", "err"); return; }
Expand All @@ -1316,7 +1326,7 @@ <h2>Save and apply</h2>
setApplyStatus("Dispatch failed (HTTP " + r.status + ").", "err");
} catch (e) {
if (btn) { btn.disabled = false; btn.textContent = "Save and apply"; }
setApplyStatus("Network error: " + escapeHtml(String(e && e.message || e)), "err");
setApplyStatus("Network error: " + String(e && e.message || e), "err");
}
}

Expand Down
130 changes: 109 additions & 21 deletions .github/pages/integrate.html
Original file line number Diff line number Diff line change
Expand Up @@ -743,21 +743,42 @@
const repo = $("repo").value.trim() || "<owner>/<repo>";
const rel = selectedRelease();
const pinned = rel && catalog.containers && rel.id !== catalog.containers.default;
const varsStep = $("varsStep");
if (!varsStep) return;
const code = text => {
const el = document.createElement("code");
el.className = "inl";
el.textContent = text;
return el;
};
if (isGitLab()) {
$("varsStep").innerHTML =
`Optional GitLab CI/CD variables can override installer defaults later; the initial scaffold records LabVIEW ${ver} in <code class="inl">.github/labview-ci.yml</code>.`;
varsStep.replaceChildren(
`Optional GitLab CI/CD variables can override installer defaults later; the initial scaffold records LabVIEW ${ver} in `,
code(".github/labview-ci.yml"),
"."
);
} else if (pinned) {
const s = source();
const srcGhcr = "ghcr.io/" + s.repo.toLowerCase();
$("varsStep").innerHTML =
`Pinning this repo to <strong>${esc(rel.label)}</strong>: the browser install sets ` +
`<code class="inl">LCWC_BASE_IMAGE=${esc(srcGhcr)}-labview-base:${esc(rel.id)}</code> and ` +
`<code class="inl">LCWC_LINUX_BASE_IMAGE=${esc(srcGhcr)}-labview:linux-${esc(rel.id)}</code> as Actions variables ` +
`(command-line installs: set them with <code class="inl">gh variable set</code>).`;
const release = document.createElement("strong");
release.textContent = rel.label;
varsStep.replaceChildren(
"Pinning this repo to ",
release,
": the browser install sets ",
code(`LCWC_BASE_IMAGE=${srcGhcr}-labview-base:${rel.id}`),
" and ",
code(`LCWC_LINUX_BASE_IMAGE=${srcGhcr}-labview:linux-${rel.id}`),
" as Actions variables (command-line installs: set them with ",
code("gh variable set"),
")."
);
} else {
$("varsStep").innerHTML =
`Optionally pin settings as Actions variables: ` +
`<code class="inl">gh variable set LABVIEW_VERSION -R ${repo} -b ${ver}</code> (has a safe fallback).`;
varsStep.replaceChildren(
"Optionally pin settings as Actions variables: ",
code(`gh variable set LABVIEW_VERSION -R ${repo} -b ${ver}`),
" (has a safe fallback)."
);
}
}

Expand Down Expand Up @@ -2351,27 +2372,94 @@
const dashLink0 = $("insDashLink"); if (dashLink0) dashLink0.style.display = "none";
const showDashLink = () => {
const dl = $("insDashLink");
if (dl) { dl.href = url; dl.innerHTML = "Open your dashboard &#8599;"; dl.style.display = ""; }
if (dl) { dl.href = url; dl.textContent = "Open your dashboard \u2197"; dl.style.display = ""; }
};

setInsStatus(`&#10003; Done \u2014 opened pull request <a href="${esc(pr.html_url)}" target="_blank" rel="noopener">#${pr.number}</a> in <code class="inl">${esc(repo)}</code>.`, "ok");

const done = [];
if (setup.kept) done.push(`Kept your existing settings &mdash; <strong>${esc(setup.kept)}</strong>.`);
if (setup.removed && setup.removed.length) done.push(`Removed <strong>${setup.removed.length}</strong> old tooling file${setup.removed.length > 1 ? "s" : ""} no longer used (in the pull request).`);
if (setup.readme) done.push(`Added a CI dashboard badge &amp; link to your README (in the pull request).`);
if (setup.workflowPerms === "done") done.push(`Set <strong>Workflow permissions</strong> to read &amp; write.`);
if (setup.toolingToken === "done") done.push(`Saved a one-time <strong>update token</strong> &mdash; future <em>Update now</em> clicks open their pull request automatically.`);
if (setup.buildImages && autoMerge) done.push(`Watching your <strong>worker container image build${setup.buildImage && setup.buildLinuxImage ? "s" : ""}</strong> &mdash; Windows and Linux image workflows are tracked separately below so it is clear which background work is still running.`);
const addDone = build => {
const item = document.createElement("li");
build(item);
done.push(item);
};
const appendText = (parent, text) => parent.appendChild(document.createTextNode(text));
const appendEmphasis = (parent, tag, text, className) => {
const el = document.createElement(tag);
if (className) el.className = className;
el.textContent = text;
parent.appendChild(el);
return el;
};
if (setup.kept) addDone(item => {
appendText(item, "Kept your existing settings - ");
appendEmphasis(item, "strong", setup.kept);
appendText(item, ".");
});
if (setup.removed && setup.removed.length) addDone(item => {
appendText(item, "Removed ");
appendEmphasis(item, "strong", setup.removed.length);
appendText(item, ` old tooling file${setup.removed.length > 1 ? "s" : ""} no longer used (in the pull request).`);
});
if (setup.readme) addDone(item => appendText(item, "Added a CI dashboard badge and link to your README (in the pull request)."));
if (setup.workflowPerms === "done") addDone(item => {
appendText(item, "Set ");
appendEmphasis(item, "strong", "Workflow permissions");
appendText(item, " to read and write.");
});
if (setup.toolingToken === "done") addDone(item => {
appendText(item, "Saved a one-time ");
appendEmphasis(item, "strong", "update token");
appendText(item, " - future ");
appendEmphasis(item, "em", "Update now");
appendText(item, " clicks open their pull request automatically.");
});
if (setup.buildImages && autoMerge) addDone(item => {
appendText(item, "Watching your ");
appendEmphasis(item, "strong", `worker container image build${setup.buildImage && setup.buildLinuxImage ? "s" : ""}`);
appendText(item, " - Windows and Linux image workflows are tracked separately below so it is clear which background work is still running.");
});
// Show the dashboard URL as PLAIN TEXT until Pages is confirmed serving it
// (revealLiveLink upgrades #insLiveUrl to a real link) so we never present a
// link that 404s. When Pages already existed it's almost certainly live, so
// that case links right away.
if (setup.pages === "done") done.push(`Enabled <strong>GitHub Pages</strong> &mdash; your dashboard will be at <span id="insLiveUrl"><code class="inl">${esc(url)}</code></span><small id="insLiveNote">It publishes within a minute of the install merge &mdash; no CI run required; the link activates here the moment it&rsquo;s live.</small>`);
else if (setup.pages === "exists") done.push(`<strong>GitHub Pages</strong> is already on &mdash; dashboard at <span id="insLiveUrl"><a href="${esc(url)}" target="_blank" rel="noopener">${esc(url)}</a></span>.`);
else if (setup.hasDashboard) done.push(`Your dashboard will be at <span id="insLiveUrl"><code class="inl">${esc(url)}</code></span> once <strong>GitHub Pages</strong> is on.`);
const appendDashboardUrl = (item, live) => {
const location = document.createElement("span");
location.id = "insLiveUrl";
if (live) {
const link = document.createElement("a");
link.href = url;
link.target = "_blank";
link.rel = "noopener";
link.textContent = url;
location.appendChild(link);
} else {
appendEmphasis(location, "code", url, "inl");
}
item.appendChild(location);
};
if (setup.pages === "done") addDone(item => {
appendText(item, "Enabled ");
appendEmphasis(item, "strong", "GitHub Pages");
appendText(item, " - your dashboard will be at ");
appendDashboardUrl(item, false);
appendEmphasis(item, "small", "It publishes within a minute of the install merge - no CI run required; the link activates here the moment it's live.").id = "insLiveNote";
});
else if (setup.pages === "exists") addDone(item => {
appendEmphasis(item, "strong", "GitHub Pages");
appendText(item, " is already on - dashboard at ");
appendDashboardUrl(item, true);
appendText(item, ".");
});
else if (setup.hasDashboard) addDone(item => {
appendText(item, "Your dashboard will be at ");
appendDashboardUrl(item, false);
appendText(item, " once ");
appendEmphasis(item, "strong", "GitHub Pages");
appendText(item, " is on.");
});
const doneEl = $("insDone");
if (doneEl) { doneEl.innerHTML = done.map(d => `<li>${d}</li>`).join(""); doneEl.style.display = done.length ? "" : "none"; }
if (doneEl) { doneEl.replaceChildren(...done); doneEl.style.display = done.length ? "" : "none"; }

const steps = [];
steps.push(`Review and merge pull request <a href="${esc(pr.html_url)}" target="_blank" rel="noopener">#${pr.number}</a>.`);
Expand Down
20 changes: 15 additions & 5 deletions .github/pages/lvci-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -1284,7 +1284,7 @@
sel.addEventListener('change', function () {
syncSteps();
var v = sel.value;
if (v && v !== cfg.sha) window.location.href = docDest(v);
if (v && v !== cfg.sha && SHA_RE.test(v)) window.location.href = docDest(v);
});
sel._lvciSync = function () { rp.refresh(); syncSteps(); };
wrap.appendChild(lbl); wrap.appendChild(prev); wrap.appendChild(rp.button); wrap.appendChild(next);
Expand Down Expand Up @@ -1953,10 +1953,20 @@
pendbar.id = 'lvci-pendbar';
pendbar.className = 'lvci-depbar';
pendbar.setAttribute('role', 'alert');
pendbar.innerHTML =
'<span class="lvci-dep-txt"><strong>\u26A0\uFE0F Dependencies need to be installed into your containers. </strong>' +
'<span class="lvci-dep-sub">Your project declares dependencies that are not yet baked into the worker container(s); container CI may error or show broken code until you update them. </span>' +
'<a href="' + navBase + '/dependencies.html">Review &amp; update dependencies \u2197</a></span>';
var pendText = document.createElement('span');
pendText.className = 'lvci-dep-txt';
var pendTitle = document.createElement('strong');
pendTitle.textContent = '\u26A0\uFE0F Dependencies need to be installed into your containers. ';
var pendDescription = document.createElement('span');
pendDescription.className = 'lvci-dep-sub';
pendDescription.textContent = 'Your project declares dependencies that are not yet baked into the worker container(s); container CI may error or show broken code until you update them. ';
var pendLink = document.createElement('a');
pendLink.href = navBase + '/dependencies.html';
pendLink.textContent = 'Review & update dependencies \u2197';
pendText.appendChild(pendTitle);
pendText.appendChild(pendDescription);
pendText.appendChild(pendLink);
pendbar.appendChild(pendText);

// Global attention bar (failure banner) — hidden until the activity poll
// finds a workflow whose newest run failed; names it + links to the run.
Expand Down
Loading
Loading