mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-10 04:36:40 +00:00
Merge branch 'main' into feature/store-i18n
Five conflicts, all resolved by combining both sides rather than taking one. main moved Moodle cURL egress and the debug level out of environment variables into site settings applied through cfg.php, and that restructure met three places where this branch had changed the same lines. vars/main.yml carried the only resolution with a real decision in it. main expects MOODLE_EGRESS_ALLOWED_PORTS to be a list and joins it; this branch had turned that name into a comma-joined string to feed the environment variable main is removing, so keeping both sides verbatim would have evaluated string plus list. The settings block now reads the list this branch introduced, MOODLE_EGRESS_WEB_PORTS, and the string is dropped with the variable it fed. MOODLE_PROXY_EXCLUDED_HOSTS and the objectfs block stay, since neither belongs to the egress restructure. env.j2 loses the egress and debug lines and keeps the SOCKS proxy block, which is this branch and which main never had. config.php loses the debug block and keeps the objectfs block for the same reason; the grep that settles it is that main carries no reference to MOODLE_EGRESS, MOODLE_DEBUG or OBJECTFS at all. 01_manager_ops.yml takes the new settings task. The cheatsheet conflict was additive on both sides, so all three rows stay. Checked after resolving, because both are documented traps of this merge: no duplicate YAML key across the seven merged YAML files, and no nocheck marker lost, with the counts matching both parents in every resolved file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
dc19615d62
20 files changed
+781
-23
No files matched your search
@@ -1,5 +1,30 @@
|
||||
# Changelog
|
||||
|
||||
## [16.2.2] - 2026-10-21
|
||||
|
||||
Fixed:
|
||||
|
||||
- Moodle: a fresh install with MCP enabled mints its token on Moodle 5.3
|
||||
- Moodle: debug deployments keep the component cache; swarm pages load fast
|
||||
- Playwright: a stuck image pull times out and retries instead of hanging
|
||||
|
||||
Version jumps (net since 16.2.1):
|
||||
|
||||
- *svc-ai-ollama*: 0.40.6 to 0.40.7
|
||||
- *svc-runner*: BuildKit v0.34.0 to v0.34.1
|
||||
- *web-app-erpnext*: v16.51.1 to v16.51.2
|
||||
- *web-app-opentalk*: RabbitMQ 4.3.6 to 4.4.0
|
||||
- *web-app-wazuh*: 4.14.6 to 4.14.9
|
||||
- *web-app-xwiki*: AI LLM 0.10 to 0.11, OIDC authenticator 2.29.0 to 2.29.1
|
||||
|
||||
Upgrade notes:
|
||||
|
||||
- Device backup: the device needs a filesystem like ext4 or xfs, not FAT
|
||||
|
||||
Contributors:
|
||||
|
||||
- [Kevin Veen-Birkenbach](https://veen.world): Moodle, Playwright pull
|
||||
|
||||
## [16.2.1] - 2026-10-20
|
||||
|
||||
Fixed:
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Release Articles
|
||||
|
||||
Write the [blog](https://blog.infinito.nexus/) article for a release, its banner image, and the Mastodon and LinkedIn posts that announce it.
|
||||
The article is one HTML file for a single WordPress Custom HTML block; the banner is a separate PNG for the post's Featured image and the image of both social posts.
|
||||
|
||||
## Inputs
|
||||
|
||||
- The release version (for example `16.0`) and its tag. When the `.0` tag was never published, the first published patch tag is the release tag and its upgrade notes count too.
|
||||
- The release sections of [CHANGELOG.md](../../../CHANGELOG.md).
|
||||
- The latest article in the Release category of the blog, as the reference for length, tone and structure.
|
||||
|
||||
## Output
|
||||
|
||||
- You MUST write every file to a work folder outside the repository and MUST NOT commit the article or the banner.
|
||||
- The work folder holds `article.html`, `banner.svg`, `banner.png` (1500 × 1000), `banner-alt.txt`, `mastodon.txt`, `linkedin.txt` and `post.md` (title, category, tags).
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Read the release sections of the changelog. Take the headline feature from the operator, otherwise the largest `Added` entry. Read the README of the role behind it so every claim is right.
|
||||
2. Fetch the reference article and measure its body, from `<div class="inf-release">` to its end: visible text characters (SVG icons excluded), words and markup lines. The new article MUST land within ±5 % on characters and on lines.
|
||||
3. Copy [templates/article.html](../../../skills/i8-release-article/templates/article.html) and fill it in its order: badge; intro and a second paragraph; the warning (major releases only, otherwise drop the block); three feature cards; one or two sections on the headline feature with a bold-lead list; the callout; an optional "Also New" section; Before You Upgrade; More Reliable (three or four fixes); Updated Applications (about thirteen chips from the version jumps, major versions first); the closing section. Repeat card, list item, table row and chip blocks as needed and remove every `{{…}}` placeholder.
|
||||
4. Write every sentence to the standard below.
|
||||
5. Copy [templates/banner.svg](../../../skills/i8-release-article/templates/banner.svg) and fill it: `{{LOGO}}` with the `file://` URL of [assets/img/logo.png](../../../assets/img/logo.png), `{{VERSION}}`, two subtitle lines of at most 34 characters, four `{{ICON_n}}` (24 × 24 outline icons) and four `{{LABEL_n}}` (plain words, at most 14 characters) for the headline feature's benefits.
|
||||
6. Render the banner with Playwright's headless shell (`~/.cache/ms-playwright/chromium_headless_shell-*/chrome-headless-shell-linux64/chrome-headless-shell`) and the flags `--disable-gpu --hide-scrollbars --allow-file-access-from-files --window-size=1500,1000 --screenshot=<work>/banner.png file://<work>/banner.svg`. Look at the PNG and fix overlaps or cut text before you go on.
|
||||
7. Write `banner-alt.txt` (one to three sentences that describe the banner and repeat its title) and the two social posts to the Social Posts rules below, with `{{ARTICLE_URL}}` where the article link goes.
|
||||
8. Verify: no `{{` left in the article; no `<code>`, command, flag, path or variable in the visible text of the article or the posts; lengths within range on every platform; every number and version matches the changelog. Render the article on a dark page at about 860 px width and look at it.
|
||||
9. Hand over the paths, the title, the category `Release`, ten to twenty tags, and the steps: paste the whole `article.html` into one WordPress Custom HTML block and set `banner.png` as the Featured image; once the article is live, replace `{{ARTICLE_URL}}` in both posts with its link and post them with `banner.png` and the alt text.
|
||||
|
||||
## Writing Standard
|
||||
|
||||
The article, the banner alt text and both social posts follow this standard. Their readers are outside the project, so deep technical detail stays out.
|
||||
|
||||
- Feature-oriented: say what the reader gets and why it matters, not how it is built.
|
||||
- No commands, flags, file paths, variable names, role names, inventory keys or code, and no `<code>` tags. Product names, application names and version numbers are fine.
|
||||
- Second person ("your servers"), present tense, short sentences, American English.
|
||||
- Every claim MUST trace back to the changelog or to the README of the role behind it. No invented numbers, benefits or comparisons. Beta features say "beta".
|
||||
- Section titles name a benefit ("A Private Network Between Your Servers"); list items open with a bold benefit lead.
|
||||
- Before You Upgrade keeps every upgrade note of the changelog and phrases the action the reader takes, not the mechanism behind it.
|
||||
|
||||
## Social Posts
|
||||
|
||||
Both posts follow the Writing Standard like the article: no commands, role names or deep technical detail, only what the reader gets. They lead with the headline feature and carry the banner with its alt text.
|
||||
|
||||
- **Mastodon** (`mastodon.txt`): at most 500 characters, counting the link as 23. An opening line naming the release, two or three sentences on the headline feature, one line on the rest of the release, a pointer to the upgrade notes, the link, then three to five CamelCase hashtags (`#InfinitoNexus`, `#SelfHosting`, `#OpenSource`, plus the headline technology). At most two emoji; plain and direct, no marketing superlatives.
|
||||
- **LinkedIn** (`linkedin.txt`): 1,000 to 1,600 characters. A hook in the first line of at most 200 characters, since LinkedIn shows only the first lines before "see more"; then short paragraphs: what the headline feature gives an organization, three benefit lines each opened by one emoji, one paragraph on the rest of the release, the upgrade pointer, the link, and three to five hashtags. Professional tone, second person, no hype words.
|
||||
|
||||
## Rules
|
||||
|
||||
- You MUST NOT publish to, or sign in to, the blog, Mastodon or LinkedIn. The operator publishes.
|
||||
- You MUST NOT add the banner to the article HTML; it belongs in the Featured image.
|
||||
@@ -40,5 +40,6 @@ from its procedure file. Run `make install-skills` to (re)install them.
|
||||
| Pushing a branch through the manual-CI draft → ready-for-review cycle | `i8-push-trigger-pull` |
|
||||
| Leading a CI run with a priority line that verifies the branch's open questions | `i8-ci-trigger-priority` |
|
||||
| Verifying from both ends at once: the CI run on a triage loop plus local iteration | `i8-verify-parallel` |
|
||||
| Writing the blog article, banner image and social posts for a release | `i8-release-article` |
|
||||
| Writing a new requirement | `i8-requirement-create` |
|
||||
| Implementing an existing requirement file end to end | `i8-requirement-implement` |
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Kevin Veen-Birkenbach <info@veen.world>
|
||||
|
||||
pkgname=infinito-nexus
|
||||
pkgver=16.2.1
|
||||
pkgver=16.2.2
|
||||
pkgrel=1
|
||||
pkgdesc="Meta package for Infinito.Nexus host dependencies (dev + CI)."
|
||||
arch=('any')
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
infinito-nexus (16.2.2-1) unstable; urgency=medium
|
||||
|
||||
Fixed:
|
||||
|
||||
- Moodle: a fresh install with MCP enabled mints its token on Moodle 5.3
|
||||
- Moodle: debug deployments keep the component cache; swarm pages load fast
|
||||
- Playwright: a stuck image pull times out and retries instead of hanging
|
||||
|
||||
Version jumps (net since 16.2.1):
|
||||
|
||||
- *svc-ai-ollama*: 0.40.6 to 0.40.7
|
||||
- *svc-runner*: BuildKit v0.34.0 to v0.34.1
|
||||
- *web-app-erpnext*: v16.51.1 to v16.51.2
|
||||
- *web-app-opentalk*: RabbitMQ 4.3.6 to 4.4.0
|
||||
- *web-app-wazuh*: 4.14.6 to 4.14.9
|
||||
- *web-app-xwiki*: AI LLM 0.10 to 0.11, OIDC authenticator 2.29.0 to 2.29.1
|
||||
|
||||
Upgrade notes:
|
||||
|
||||
- Device backup: the device needs a filesystem like ext4 or xfs, not FAT
|
||||
|
||||
Contributors:
|
||||
|
||||
- [Kevin Veen-Birkenbach](https://veen.world): Moodle, Playwright pull
|
||||
|
||||
-- Kevin Veen-Birkenbach <kevin@veen.world> Wed, 21 Oct 2026 13:00:11 +0200
|
||||
|
||||
infinito-nexus (16.2.1-1) unstable; urgency=medium
|
||||
|
||||
Fixed:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: infinito-nexus
|
||||
Version: 16.2.1
|
||||
Version: 16.2.2
|
||||
Release: 1%{?dist}
|
||||
Summary: Meta package for Infinito.Nexus host dependencies
|
||||
|
||||
@@ -58,6 +58,30 @@ install -d %{buildroot}%{_docdir}/%{name}
|
||||
%doc %{_docdir}/%{name}/DEPENDENCIES
|
||||
|
||||
%changelog
|
||||
* Wed Oct 21 2026 Kevin Veen-Birkenbach <kevin@veen.world> - 16.2.2-1
|
||||
- Fixed:
|
||||
|
||||
- - Moodle: a fresh install with MCP enabled mints its token on Moodle 5.3
|
||||
- - Moodle: debug deployments keep the component cache; swarm pages load fast
|
||||
- - Playwright: a stuck image pull times out and retries instead of hanging
|
||||
|
||||
- Version jumps (net since 16.2.1):
|
||||
|
||||
- - *svc-ai-ollama*: 0.40.6 to 0.40.7
|
||||
- - *svc-runner*: BuildKit v0.34.0 to v0.34.1
|
||||
- - *web-app-erpnext*: v16.51.1 to v16.51.2
|
||||
- - *web-app-opentalk*: RabbitMQ 4.3.6 to 4.4.0
|
||||
- - *web-app-wazuh*: 4.14.6 to 4.14.9
|
||||
- - *web-app-xwiki*: AI LLM 0.10 to 0.11, OIDC authenticator 2.29.0 to 2.29.1
|
||||
|
||||
- Upgrade notes:
|
||||
|
||||
- - Device backup: the device needs a filesystem like ext4 or xfs, not FAT
|
||||
|
||||
- Contributors:
|
||||
|
||||
- - [Kevin Veen-Birkenbach](https://veen.world): Moodle, Playwright pull
|
||||
|
||||
* Tue Oct 20 2026 Kevin Veen-Birkenbach <kevin@veen.world> - 16.2.1-1
|
||||
- Fixed:
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "infinito-nexus"
|
||||
version = "16.2.1"
|
||||
version = "16.2.2"
|
||||
description = "Infinito.Nexus"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
|
||||
@@ -13,7 +13,7 @@ ollama:
|
||||
backup:
|
||||
no_stop_required: true
|
||||
image: ollama/ollama
|
||||
version: 0.40.6
|
||||
version: 0.40.7
|
||||
name: ollama
|
||||
gpu: true
|
||||
min_storage: 3473MB
|
||||
|
||||
@@ -8,8 +8,8 @@ whitelist:
|
||||
- https://plc.directory
|
||||
- https://bsky.social
|
||||
- https://api.bsky.app
|
||||
- https://public.api.bsky.app
|
||||
- https://events.bsky.app
|
||||
- https://public.api.bsky.app # nocheck: url Reason: CSP origin, not a page; its root intermittently answers HTTP 404 to CI runners
|
||||
- https://*.workers.bsky.app # nocheck: url
|
||||
- https://statsigapi.net # nocheck: url
|
||||
- https://video.bsky.app
|
||||
|
||||
@@ -68,7 +68,7 @@ erpnext:
|
||||
enabled: true
|
||||
shared: true
|
||||
image: frappe/erpnext
|
||||
version: "v16.51.1"
|
||||
version: "v16.52.0"
|
||||
name: erpnext
|
||||
min_storage: 1017MB
|
||||
ports:
|
||||
|
||||
@@ -58,10 +58,6 @@ if (explode(':', $_SERVER['HTTP_HOST'] ?? '', 2)[0] === $_moodle_internal_host)
|
||||
$_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
|
||||
$_moodle_debug = moodle_env_bool('MOODLE_DEBUG');
|
||||
$CFG->debug = $_moodle_debug ? 32767 : 0;
|
||||
$CFG->debugdisplay = $_moodle_debug;
|
||||
|
||||
if (moodle_env_bool('MOODLE_OBJECTFS_ENABLED')
|
||||
&& is_file(moodle_env('MOODLE_OBJECTFS_READY_FILE'))) {
|
||||
$CFG->alternative_file_system_class = '\\tool_objectfs\\s3_file_system';
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<?php
|
||||
// nocheck: mirrored-unit-test - a CLI_SCRIPT that requires Moodle's config.php and
|
||||
// externallib at the top level and then writes through set_config and the webservice
|
||||
// manager; nothing loads without a provisioned Moodle install
|
||||
// the webservice library at the top level and then writes through set_config and the
|
||||
// webservice manager; nothing loads without a provisioned Moodle install
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require(getenv('MOODLE_CONFIG'));
|
||||
require_once($CFG->libdir . '/externallib.php');
|
||||
require_once($CFG->dirroot . '/webservice/lib.php');
|
||||
|
||||
$shortname = (string) getenv('MCP_SERVICE_SHORTNAME');
|
||||
@@ -43,8 +42,6 @@ foreach ($functions as $function) {
|
||||
}
|
||||
}
|
||||
|
||||
require_once($CFG->dirroot . '/user/lib.php');
|
||||
|
||||
$username = (string) getenv('MCP_ACCOUNT_USERNAME');
|
||||
$capabilities = array_filter(array_map('trim', explode(',', (string) getenv('MCP_ROLE_CAPABILITIES'))));
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
@@ -74,6 +74,17 @@
|
||||
changed_when: moodle_admin_password.rc == 0
|
||||
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||
|
||||
- name: "⚙️ Apply Moodle's cURL egress policy and debug level to the site config"
|
||||
ansible.builtin.shell: >
|
||||
container exec --user {{ MOODLE_RUNTIME_USER }} {{ MOODLE_CONTAINER_ADDRESS }}
|
||||
php {{ [MOODLE_CLI_DIR, 'cfg.php'] | path_join }}
|
||||
--name={{ item.name | quote }}
|
||||
--set={{ item.value | quote }}
|
||||
loop: "{{ MOODLE_EGRESS_SETTINGS + MOODLE_DEBUG_SETTINGS }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
changed_when: false
|
||||
|
||||
- name: "📂 Include ownership settings tasks for moodle"
|
||||
include_tasks: 03_ownership.yml
|
||||
|
||||
|
||||
@@ -16,16 +16,12 @@ MOODLE_DB_PREFIX=mdl_
|
||||
MOODLE_REVERSEPROXY=false
|
||||
MOODLE_SSLPROXY={{ lookup('tls', application_id, 'enabled') | string | lower }}
|
||||
|
||||
MOODLE_EGRESS_BLOCKED_HOSTS={{ MOODLE_EGRESS_BLOCKED_HOSTS | join(',') }}
|
||||
MOODLE_EGRESS_ALLOWED_PORTS={{ MOODLE_EGRESS_ALLOWED_PORTS }}
|
||||
{% if MOODLE_OIDC_SOCKS_PROXY | length > 0 %}
|
||||
http_proxy={{ MOODLE_OIDC_SOCKS_PROXY }}
|
||||
https_proxy={{ MOODLE_OIDC_SOCKS_PROXY }}
|
||||
no_proxy={{ MOODLE_PROXY_EXCLUDED_HOSTS | unique | join(',') }}
|
||||
{% endif %}
|
||||
|
||||
MOODLE_DEBUG={{ MODE_DEBUG | bool }}
|
||||
|
||||
MOODLE_SITE_NAME={{ MOODLE_SITE_TITLE | dotenv_quote }}
|
||||
MOODLE_ADMIN_EMAIL={{ lookup('config', application_id, 'users.platform_administrator.email') }}
|
||||
|
||||
|
||||
@@ -85,8 +85,18 @@ MOODLE_EGRESS_BLOCKED_HOSTS:
|
||||
MOODLE_EGRESS_WEB_PORTS:
|
||||
- "80"
|
||||
- "443"
|
||||
MOODLE_EGRESS_ALLOWED_PORTS: "{{ (MOODLE_EGRESS_WEB_PORTS + ([MOODLE_LITELLM_CHAT_ENDPOINT | urlsplit('port') | string] if MOODLE_LITELLM_ENABLED | bool else []))
|
||||
| join(',') }}"
|
||||
MOODLE_EGRESS_NEWLINE: "\n"
|
||||
MOODLE_EGRESS_SETTINGS:
|
||||
- name: curlsecurityblockedhosts
|
||||
value: "{{ MOODLE_EGRESS_BLOCKED_HOSTS | join(MOODLE_EGRESS_NEWLINE) }}"
|
||||
- name: curlsecurityallowedport
|
||||
value: "{{ (MOODLE_EGRESS_WEB_PORTS + ([MOODLE_LITELLM_CHAT_ENDPOINT | urlsplit('port') | string] if MOODLE_LITELLM_ENABLED | bool else [])) | join(MOODLE_EGRESS_NEWLINE)
|
||||
}}"
|
||||
MOODLE_DEBUG_SETTINGS:
|
||||
- name: debug
|
||||
value: "{{ (MODE_DEBUG | bool) | ternary('32767', '0') }}"
|
||||
- name: debugdisplay
|
||||
value: "{{ (MODE_DEBUG | bool) | ternary('1', '0') }}"
|
||||
MOODLE_PROXY_EXCLUDED_HOSTS: "{{ lookup('proxy_excluded_hosts', application_id) + [MOODLE_MCP_SERVICE_KEY] + ([MOODLE_LITELLM_CHAT_ENDPOINT | urlsplit('hostname')]
|
||||
if MOODLE_LITELLM_ENABLED | bool else []) }}"
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ n8n:
|
||||
backup:
|
||||
no_stop_required: false
|
||||
image: docker.n8n.io/n8nio/n8n
|
||||
version: "2.45.0"
|
||||
version: "2.45.1"
|
||||
update:
|
||||
type: registry_tags
|
||||
image: docker.n8n.io/n8nio/n8n
|
||||
|
||||
@@ -5,7 +5,7 @@ mechanism: extension
|
||||
source: upstream
|
||||
bridges:
|
||||
- sso
|
||||
version: "2.29.0"
|
||||
version: "2.29.1"
|
||||
update:
|
||||
type: http_regex
|
||||
url: https://maven.xwiki.org/releases/org/xwiki/contrib/oidc/oidc-authenticator/maven-metadata.xml
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: i8-release-article
|
||||
description: >
|
||||
Write the blog.infinito.nexus article for a release, its banner image for
|
||||
the Featured image, and the Mastodon and LinkedIn posts that announce it,
|
||||
from the changelog, in the blog's release style and a non-technical,
|
||||
feature-oriented voice for readers outside the project. Use when the
|
||||
operator asks for a release article, blog post, release banner or release
|
||||
announcement on social media. Infinito.Nexus specific.
|
||||
---
|
||||
|
||||
Follow the instructions from AGENTS.md, then write the release article by
|
||||
following the procedure in `docs/agents/action/release-article.md` (relative
|
||||
to the Infinito.Nexus repository root) exactly. That document is the source
|
||||
of truth; this skill only routes you there and ships the article and banner
|
||||
templates under `templates/`. Begin by clarifying every open requirement with
|
||||
the `active-listening` skill (release version, headline feature), then work
|
||||
under the `robot` skill.
|
||||
@@ -0,0 +1,501 @@
|
||||
<style>
|
||||
.inf-release {
|
||||
--bg-card: #111827;
|
||||
--text-main: #f8fafc;
|
||||
--text-muted: #94a3b8;
|
||||
--border-subtle: #1e293b;
|
||||
--brand-indigo: #6366f1;
|
||||
--brand-purple: #8b5cf6;
|
||||
--brand-cyan: #06b6d4;
|
||||
--brand-red: #ef4444;
|
||||
|
||||
--gradient-main: linear-gradient(
|
||||
135deg,
|
||||
var(--brand-indigo),
|
||||
var(--brand-purple),
|
||||
var(--brand-cyan)
|
||||
);
|
||||
|
||||
--gradient-glow: linear-gradient(
|
||||
135deg,
|
||||
rgba(99,102,241,.15),
|
||||
rgba(139,92,246,.15),
|
||||
rgba(6,182,212,.15)
|
||||
);
|
||||
|
||||
--gradient-alert: linear-gradient(
|
||||
135deg,
|
||||
rgba(239,68,68,.15),
|
||||
rgba(139,92,246,.1)
|
||||
);
|
||||
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
}
|
||||
|
||||
.inf-release *,
|
||||
.inf-release *::before,
|
||||
.inf-release *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.inf-release p {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.inf-release a {
|
||||
color: #7dd3fc;
|
||||
}
|
||||
|
||||
.inf-release strong {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.inf-release .inf-badge {
|
||||
display: inline-block;
|
||||
margin: 0 0 1.5rem;
|
||||
padding: .4rem 1rem;
|
||||
|
||||
border: 1px solid rgba(99,102,241,.35);
|
||||
border-radius: 999px;
|
||||
|
||||
background: var(--gradient-glow);
|
||||
color: var(--brand-cyan);
|
||||
|
||||
font-size: .8rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: .1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.inf-release .inf-intro {
|
||||
font-size: 1.08em;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.inf-release .inf-warning {
|
||||
margin: 2rem 0;
|
||||
padding: 1.25rem 1.4rem;
|
||||
|
||||
background: var(--gradient-alert);
|
||||
|
||||
border: 1px solid rgba(239,68,68,.35);
|
||||
border-radius: 10px;
|
||||
|
||||
color: #fca5a5;
|
||||
}
|
||||
|
||||
.inf-release .inf-warning strong {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.inf-release .inf-warning a {
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
.inf-release .inf-features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0,1fr));
|
||||
gap: 1rem;
|
||||
|
||||
margin: 2.5rem 0;
|
||||
}
|
||||
|
||||
.inf-release .inf-card {
|
||||
min-width: 0;
|
||||
|
||||
padding: 1.35rem;
|
||||
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.inf-release .inf-card svg {
|
||||
display: block;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
|
||||
margin-bottom: 1rem;
|
||||
|
||||
color: var(--brand-cyan);
|
||||
}
|
||||
|
||||
.inf-release .inf-card h3 {
|
||||
margin: 0 0 .65rem;
|
||||
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.inf-release .inf-card p {
|
||||
margin: 0;
|
||||
|
||||
color: var(--text-muted);
|
||||
font-size: .93rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.inf-release h2 {
|
||||
margin-top: 2.8rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .7rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-heading::before {
|
||||
content: "";
|
||||
|
||||
width: 4px;
|
||||
height: 1.25em;
|
||||
|
||||
flex: 0 0 4px;
|
||||
|
||||
border-radius: 3px;
|
||||
background: var(--gradient-main);
|
||||
}
|
||||
|
||||
.inf-release .inf-list {
|
||||
margin: 1.2rem 0;
|
||||
padding: 0;
|
||||
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.inf-release .inf-list li {
|
||||
position: relative;
|
||||
|
||||
margin-bottom: .65rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-list li::before {
|
||||
content: "✦";
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
color: var(--brand-cyan);
|
||||
}
|
||||
|
||||
.inf-release .inf-callout {
|
||||
margin: 2.3rem 0;
|
||||
padding: 1.5rem;
|
||||
|
||||
background: rgba(17,24,39,.7);
|
||||
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-left: 4px solid var(--brand-purple);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.inf-release .inf-callout h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.inf-release code {
|
||||
padding: .15em .35em;
|
||||
|
||||
background: rgba(255,255,255,.07);
|
||||
|
||||
border-radius: 4px;
|
||||
|
||||
color: var(--brand-cyan);
|
||||
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.inf-release .inf-table-wrap {
|
||||
overflow-x: auto;
|
||||
|
||||
margin: 1.5rem 0 2.5rem;
|
||||
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.inf-release table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.inf-release th,
|
||||
.inf-release td {
|
||||
padding: 1rem;
|
||||
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
|
||||
.inf-release th {
|
||||
background: rgba(17,24,39,.8);
|
||||
}
|
||||
|
||||
.inf-release tr:last-child td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.inf-release .inf-apps {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: .55rem;
|
||||
|
||||
margin: 1.4rem 0 2.5rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-app {
|
||||
display: inline-block;
|
||||
|
||||
padding: .4rem .7rem;
|
||||
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 7px;
|
||||
|
||||
font-size: .88rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-cta {
|
||||
margin-top: 3rem;
|
||||
padding-top: 2rem;
|
||||
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.inf-release .inf-buttons {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-btn {
|
||||
display: inline-block;
|
||||
|
||||
margin: .3rem;
|
||||
padding: .7rem 1.15rem;
|
||||
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 7px;
|
||||
|
||||
background: var(--bg-card);
|
||||
|
||||
color: inherit !important;
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.inf-release .inf-btn-primary {
|
||||
border: none;
|
||||
|
||||
background: var(--gradient-main);
|
||||
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.inf-release .inf-features {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.inf-release .inf-warning,
|
||||
.inf-release .inf-callout,
|
||||
.inf-release .inf-card {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.inf-release .inf-btn {
|
||||
display: block;
|
||||
margin: .6rem 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="inf-release">
|
||||
|
||||
<div class="inf-badge">
|
||||
Release {{VERSION}}
|
||||
</div>
|
||||
|
||||
<p class="inf-intro">
|
||||
{{INTRO}}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{{INTRO_MORE}}
|
||||
</p>
|
||||
|
||||
|
||||
<div class="inf-warning">
|
||||
🚨 <strong>{{VERSION}} is a major release.</strong>
|
||||
{{WARNING}}
|
||||
<strong>
|
||||
Read <a href="#before-you-upgrade">Before You Upgrade</a> before you deploy.
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="inf-features">
|
||||
|
||||
<div class="inf-card">
|
||||
<svg fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round"
|
||||
viewBox="0 0 24 24">
|
||||
{{CARD_ICON}}
|
||||
</svg>
|
||||
|
||||
<h3>{{CARD_TITLE}}</h3>
|
||||
|
||||
<p>
|
||||
{{CARD_TEXT}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="inf-heading">
|
||||
{{SECTION_TITLE}}
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
{{SECTION_TEXT}}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>
|
||||
{{LIST_LEAD}}
|
||||
</strong>
|
||||
</p>
|
||||
|
||||
<ul class="inf-list">
|
||||
<li>
|
||||
<strong>{{ITEM_LEAD}}:</strong> {{ITEM_TEXT}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="inf-callout">
|
||||
|
||||
<h3>{{CALLOUT_TITLE}}</h3>
|
||||
|
||||
<p>
|
||||
{{CALLOUT_TEXT}}
|
||||
</p>
|
||||
|
||||
<ul class="inf-list">
|
||||
<li>
|
||||
<strong>{{ITEM_LEAD}}:</strong>
|
||||
{{ITEM_TEXT}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2 id="before-you-upgrade" class="inf-heading">
|
||||
Before You Upgrade
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
{{UPGRADE_LEAD}}
|
||||
</p>
|
||||
|
||||
<div class="inf-table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>If you…</th>
|
||||
<th>Then…</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td><strong>{{IF_YOU}}</strong></td>
|
||||
<td>
|
||||
{{THEN}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="inf-heading">
|
||||
More Reliable
|
||||
</h2>
|
||||
|
||||
<ul class="inf-list">
|
||||
<li>
|
||||
<strong>{{FIX_LEAD}}:</strong>
|
||||
{{FIX_TEXT}}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 class="inf-heading">
|
||||
Updated Applications
|
||||
</h2>
|
||||
|
||||
<div class="inf-apps">
|
||||
<span class="inf-app">{{APP}} {{APP_VERSION}}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="inf-cta">
|
||||
|
||||
<h2>{{CLOSING_TITLE}}</h2>
|
||||
|
||||
<p>
|
||||
{{CLOSING_TEXT}}
|
||||
</p>
|
||||
|
||||
<div class="inf-buttons">
|
||||
|
||||
<a
|
||||
href="https://s.infinito.nexus/changelog"
|
||||
class="inf-btn inf-btn-primary"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
Full {{RELEASE_TAG}} Changelog
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://github.com/infinito-nexus/core"
|
||||
class="inf-btn"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
GitHub Repository
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://cybermaster.space/"
|
||||
class="inf-btn"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
Contact Infinito.Nexus Team
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,102 @@
|
||||
<svg viewBox="0 0 1500 1000" width="1500" height="1000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<radialGradient id="bg" cx="750" cy="330" r="760" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1D34C9" stop-opacity=".75"/>
|
||||
<stop offset=".45" stop-color="#0B1233"/>
|
||||
<stop offset="1" stop-color="#050812"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="title" x1="980" y1="0" x2="1240" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#6366f1"/>
|
||||
<stop offset="1" stop-color="#22d3ee"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="sub" x1="290" y1="0" x2="1210" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#a78bfa"/>
|
||||
<stop offset=".55" stop-color="#6366f1"/>
|
||||
<stop offset="1" stop-color="#22d3ee"/>
|
||||
</linearGradient>
|
||||
<pattern id="dots" width="18" height="18" patternUnits="userSpaceOnUse">
|
||||
<circle cx="2" cy="2" r="1.6" fill="#7d96ff"/>
|
||||
</pattern>
|
||||
<clipPath id="globe"><circle cx="750" cy="330" r="330"/></clipPath>
|
||||
<clipPath id="logo"><circle cx="750" cy="330" r="170"/></clipPath>
|
||||
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="9"/></filter>
|
||||
<filter id="soft" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="22"/></filter>
|
||||
<g id="panel">
|
||||
<rect x="-110" y="-75" width="220" height="150" rx="20" fill="#4f6bff" fill-opacity=".09" stroke="#8ea2ff" stroke-opacity=".55" stroke-width="2"/>
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<rect width="1500" height="1000" fill="url(#bg)"/>
|
||||
|
||||
<g clip-path="url(#globe)" opacity=".22">
|
||||
<rect x="420" y="0" width="660" height="660" fill="url(#dots)"/>
|
||||
</g>
|
||||
<g fill="none" stroke="#7d96ff" stroke-opacity=".28" stroke-width="2">
|
||||
<circle cx="750" cy="330" r="330"/>
|
||||
<ellipse cx="750" cy="330" rx="330" ry="120"/>
|
||||
<ellipse cx="750" cy="330" rx="140" ry="330"/>
|
||||
</g>
|
||||
|
||||
<g fill="none" stroke-linecap="round">
|
||||
<g stroke="#4f6bff" stroke-width="12" opacity=".7" filter="url(#glow)">
|
||||
<path d="M335 245 C 450 245, 500 290, 584 318"/>
|
||||
<path d="M335 545 C 450 545, 500 420, 590 385"/>
|
||||
<path d="M1165 245 C 1050 245, 1000 290, 916 318"/>
|
||||
<path d="M1165 545 C 1050 545, 1000 420, 910 385"/>
|
||||
</g>
|
||||
<g stroke="#9fb0ff" stroke-width="4">
|
||||
<path d="M335 245 C 450 245, 500 290, 584 318"/>
|
||||
<path d="M335 545 C 450 545, 500 420, 590 385"/>
|
||||
<path d="M1165 245 C 1050 245, 1000 290, 916 318"/>
|
||||
<path d="M1165 545 C 1050 545, 1000 420, 910 385"/>
|
||||
</g>
|
||||
</g>
|
||||
<g fill="#e0f2fe">
|
||||
<circle cx="470" cy="262" r="6"/>
|
||||
<circle cx="470" cy="500" r="6"/>
|
||||
<circle cx="1030" cy="262" r="6"/>
|
||||
<circle cx="1030" cy="500" r="6"/>
|
||||
</g>
|
||||
|
||||
<use href="#panel" xlink:href="#panel" x="225" y="245"/>
|
||||
<use href="#panel" xlink:href="#panel" x="225" y="545"/>
|
||||
<use href="#panel" xlink:href="#panel" x="1275" y="245"/>
|
||||
<use href="#panel" xlink:href="#panel" x="1275" y="545"/>
|
||||
<g fill="none" stroke="#67e8f9" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g transform="translate(189 209) scale(3)">{{ICON_1}}</g>
|
||||
<g transform="translate(189 509) scale(3)">{{ICON_2}}</g>
|
||||
<g transform="translate(1239 209) scale(3)">{{ICON_3}}</g>
|
||||
<g transform="translate(1239 509) scale(3)">{{ICON_4}}</g>
|
||||
</g>
|
||||
<g font-family="'JetBrains Mono','SFMono-Regular',Menlo,Consolas,monospace" font-size="22" font-weight="600" fill="#a5b4fc" text-anchor="middle">
|
||||
<text x="225" y="356">{{LABEL_1}}</text>
|
||||
<text x="225" y="656">{{LABEL_2}}</text>
|
||||
<text x="1275" y="356">{{LABEL_3}}</text>
|
||||
<text x="1275" y="656">{{LABEL_4}}</text>
|
||||
</g>
|
||||
|
||||
<ellipse cx="750" cy="636" rx="300" ry="30" fill="none" stroke="#4f6bff" stroke-width="10" opacity=".55" filter="url(#glow)"/>
|
||||
<ellipse cx="750" cy="636" rx="300" ry="30" fill="#0b1233" stroke="#6d83ff" stroke-width="3"/>
|
||||
<rect x="560" y="520" width="380" height="54" rx="14" fill="#0e1430" stroke="#3b4fc4" stroke-width="2"/>
|
||||
<rect x="560" y="580" width="380" height="54" rx="14" fill="#0e1430" stroke="#3b4fc4" stroke-width="2"/>
|
||||
<rect x="592" y="544" width="66" height="6" rx="3" fill="#22d3ee"/>
|
||||
<rect x="592" y="604" width="66" height="6" rx="3" fill="#22d3ee"/>
|
||||
<g fill="#7dd3fc">
|
||||
<circle cx="896" cy="547" r="4"/><circle cx="912" cy="547" r="4"/>
|
||||
<circle cx="896" cy="607" r="4"/><circle cx="912" cy="607" r="4"/>
|
||||
</g>
|
||||
|
||||
<circle cx="750" cy="330" r="186" fill="#4f6bff" opacity=".6" filter="url(#soft)"/>
|
||||
<circle cx="750" cy="330" r="176" fill="#ffffff"/>
|
||||
<image href="{{LOGO}}" xlink:href="{{LOGO}}" x="576" y="156" width="348" height="348" preserveAspectRatio="xMidYMid slice" clip-path="url(#logo)"/>
|
||||
<circle cx="750" cy="330" r="176" fill="none" stroke="#8ea2ff" stroke-width="5"/>
|
||||
|
||||
<rect x="636" y="686" width="228" height="52" rx="26" fill="#22d3ee" fill-opacity=".08" stroke="#22d3ee" stroke-width="2"/>
|
||||
<text x="750" y="720" text-anchor="middle" font-family="Inter,'Segoe UI',Roboto,system-ui,sans-serif" font-size="22" font-weight="700" letter-spacing="4" fill="#67e8f9">RELEASE {{VERSION}}</text>
|
||||
|
||||
<text x="750" y="828" text-anchor="middle" font-family="Inter,'Segoe UI',Roboto,system-ui,sans-serif" font-size="96" font-weight="800" letter-spacing="-2" fill="#f8fafc">Infinito.Nexus <tspan fill="url(#title)">{{VERSION}}</tspan></text>
|
||||
<g font-family="Inter,'Segoe UI',Roboto,system-ui,sans-serif" font-size="50" font-weight="800" fill="url(#sub)" text-anchor="middle">
|
||||
<text x="750" y="904">{{SUBTITLE_1}}</text>
|
||||
<text x="750" y="964">{{SUBTITLE_2}}</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
Reference in new issue
Block a user