Skip to content
Merged
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
27 changes: 20 additions & 7 deletions docs/developer/projects/eduide-shared-cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,39 @@ The **EduIDE Shared Cache** repository provides a high-performance, Kubernetes-n
## Key Features

- **Gradle Compatibility**: Fully implements the Gradle HTTP Build Cache protocol for seamless integration.
- **Persistent Storage**: Utilizes MinIO (S3-compatible object storage) for reliable and scalable storage of cache artifacts.
- **Access Control**: Features HTTP Basic Authentication to ensure secure access to the cache.
- **In-Memory Storage**: Uses Redis for fast cache lookups and storage of build artifacts.
- **Role-Based Authentication**: HTTP Basic Authentication with separate reader and writer roles for fine-grained access control.
- **Kubernetes-Native**: Designed with containerization in mind, including production-ready Helm charts for easy deployment.
- **Observability**: Built-in support for Prometheus metrics and structured JSON logging for effective monitoring.
- **Resource Efficient**: Lightweight implementation with a minimal CPU and memory footprint.
- **Observability**: Built-in Prometheus metrics, pre-built Grafana dashboard, Redis exporter sidecar, and structured JSON logging.
- **Dependency Proxy**: Optional Reposilite integration for caching Maven/Gradle dependencies.
- **Health Checks**: Kubernetes-ready liveness (`/ping`) and readiness (`/health`) probes.
- **Resource Efficient**: Lightweight implementation with a minimal CPU and memory footprint (~256Mi RAM, ~100m CPU).

## Technical Details

- **Language**: Go (Golang)
- **Web Framework**: [Gin](https://github.com/gin-gonic/gin)
- **Storage Backend**: [MinIO](https://min.io/)
- **Storage Backend**: [Redis](https://redis.io/) 7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

What is the latest stable version of Redis as of March 2026?

💡 Result:

The latest stable version of Redis Open Source as of March 2026 is 8.6.1.

Citations:


🏁 Script executed:

#!/bin/bash
# Check for any Redis version references in the codebase
rg -i 'redis.*version|redis.*[0-9]+\.[0-9]+' --type yaml --type json -C2

Repository: EduIDE/Docs

Length of output: 37


Update Redis to version 8.6.1 or at minimum to the latest Redis 8.x release, as Redis 7 is now outdated. The current stable version as of March 2026 is Redis 8.6.1.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/developer/projects/eduide-shared-cache.md` at line 27, The docs entry
"Storage Backend: Redis 7" should be updated to reference Redis 8.6.1 (or at
minimum the latest Redis 8.x); change the text "Redis 7" to "Redis 8.6.1" (or
"Redis 8.x (recommended 8.6.1)") in the
docs/developer/projects/eduide-shared-cache.md file so the storage backend
version is current, and update any accompanying link if you want it to point to
the Redis 8.x release notes or download page for clarity.

- **Deployment**: Docker, Kubernetes, Helm
- **Key Dependencies**:
- `github.com/gin-gonic/gin`: HTTP web framework.
- `github.com/minio/minio-go/v7`: Client for MinIO interaction.
- `github.com/redis/go-redis/v9`: Redis client for storage operations.
- `github.com/prometheus/client_golang`: Prometheus metrics instrumentation.

## API Endpoints

| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| `/ping` | GET | No | Health check (liveness probe) |
| `/health` | GET | No | Storage connectivity check (readiness probe) |
| `/metrics` | GET | No | Prometheus metrics |
| `/cache/:key` | GET | reader/writer | Retrieve cache entry |
| `/cache/:key` | HEAD | reader/writer | Check if cache entry exists |
| `/cache/:key` | PUT | writer only | Store cache entry |

## Integration

In the EduIDE ecosystem, **EduIDE Shared Cache** is an essential tool for developer productivity and CI/CD efficiency. It is used to accelerate the build processes of various components, such as the Theia IDE blueprints and other microservices, by caching intermediate build results. This is particularly beneficial in monorepo structures or large multi-module projects common in the Artemis environment.
In the EduIDE ecosystem, **EduIDE Shared Cache** serves as a shared Gradle build cache for students working in cloud IDE sessions. When a student triggers a Gradle build, previously computed build outputs are served from the shared cache, significantly reducing build times. Since many students work on the same exercise templates, cache hit rates are high and redundant compilation work is avoided across sessions.

## Repository

Expand Down
24 changes: 12 additions & 12 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ const config: Config = {
},
items: [
{
to: '/developer/intro',
label: 'Developer',
to: '/instructor/intro',
label: 'Instructor',
position: 'left',
},
{
to: '/instructor/intro',
label: 'Instructor',
to: '/student/intro',
label: 'Student',
position: 'left',
},
{
Expand All @@ -105,8 +105,8 @@ const config: Config = {
position: 'left',
},
{
to: '/student/intro',
label: 'Student',
to: '/developer/intro',
label: 'Developer',
position: 'left',
},
{
Expand All @@ -122,21 +122,21 @@ const config: Config = {
{
title: 'Sections',
items: [
{
label: 'Developer',
to: '/developer/intro',
},
{
label: 'Instructor',
to: '/instructor/intro',
},
{
label: 'Student',
to: '/student/intro',
},
{
label: 'Admins',
to: '/admins/intro',
},
{
label: 'Student',
to: '/student/intro',
label: 'Developer',
to: '/developer/intro',
},
],
},
Expand Down
10 changes: 10 additions & 0 deletions src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
--ifm-background-color: #2a2a40;
}

[data-theme='dark'] .button.button--secondary:not(#_):not(#_) {
background-color: rgba(255, 255, 255, 0.08);
color: #e2e8f0;
}

[data-theme='dark'] .button.button--secondary:not(#_):not(#_):hover {
background-color: rgba(255, 255, 255, 0.14);
color: #e2e8f0;
Comment on lines +33 to +40

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify no chained simple :not() remains (expected: no matches)
rg -nP --type=css ':not\([^)]*\):not\([^)]*\)'

# Verify complex notation exists for the updated dark secondary button selectors (expected: matches)
rg -nP --type=css "\[data-theme='dark'\]\s+\.button\.button--secondary:not\(`#_`#_\)(:hover)?\s*\{"

Repository: EduIDE/Docs

Length of output: 232


🏁 Script executed:

# Find stylelint configuration files
git ls-files | grep -E "stylelint|\.stylelintrc" | head -20

Repository: EduIDE/Docs

Length of output: 37


🏁 Script executed:

# Search for stylelint config in common locations
find . -maxdepth 2 -type f \( -name ".stylelintrc*" -o -name "stylelint.config.js" -o -name "stylelint.config.mjs" \) 2>/dev/null

Repository: EduIDE/Docs

Length of output: 74


🏁 Script executed:

# Check package.json for stylelint configuration
head -100 package.json | grep -A 20 "stylelint"

Repository: EduIDE/Docs

Length of output: 37


🏁 Script executed:

cat .stylelintrc.json

Repository: EduIDE/Docs

Length of output: 1061


🌐 Web query:

stylelint selector-not-notation rule default simple complex

💡 Result:

The stylelint rule "selector-not-notation" enforces the notation used in :not pseudo-class selectors, with two options: "simple" or "complex". There is no default value; the rule must be explicitly configured with one of these options to be enabled, as no rules are turned on by default in stylelint. "simple" enforces Selectors Level 3 notation (backwards compatible with older browsers), disallowing complex selectors like :not(a, div) or :not(a.foo), but allowing :not(a):not(div) or :not(a). "complex" enforces modern Selectors Level 4 notation, disallowing simple chained notation like :not(a):not(div), but allowing :not(a, div), :not(a.foo), and more complex forms like :not(a).foo:not(:empty). Note that switching notations can change selector specificity, e.g., a:not(.foo,.bar) has specificity 0,1,1 while a:not(.foo):not(.bar) has 0,2,1. The rule is autofixable.

Citations:


🌐 Web query:

CSS :not() pseudo-class selector complex notation syntax

💡 Result:

The CSS :not pseudo-class uses the syntax :not(<>) where <> is a comma-separated list of one or more selectors. It matches elements that do not match any of the selectors in the list. The argument cannot include pseudo-elements but supports simple, compound, and complex selectors (Selectors Level 4). Examples: - Basic: p:not(.fancy) - selects p elements without class "fancy" - Multiple: p:not(.foo, .bar) - selects p elements without class "foo" or "bar" (equivalent to p:not(.foo):not(.bar)) - Complex: p:not(article *) - selects p elements not descendants of article - With invalid selectors: Use :not(:is(.foo, :invalid)) to avoid invalidating the rule, as direct invalid selectors invalidate the entire :not Key notes: - Specificity is that of the most specific selector in the :not argument. - Invalid selectors in the list invalidate the whole rule (unless wrapped in :is). - Cannot nest :not or use pseudo-elements in argument. - Defined in Selectors Level 4 (updated from Level 3's single simple selector).

Citations:


🌐 Web query:

stylelint-config-standard-scss default rules enabled selector-not-notation

💡 Result:

Yes, the "selector-not-notation" rule is enabled by default in stylelint-config-standard-scss. It inherits the setting from stylelint-config-standard, where it is explicitly set to "complex" ('selector-not-notation': 'complex'). The stylelint-config-standard-scss config extends stylelint-config-standard without overriding this rule, as confirmed by its index.js file contents, which do not mention "selector-not-notation".

Citations:


🏁 Script executed:

# Check if there's a CI config that runs stylelint
git ls-files | grep -E "\.(github/workflows|gitlab-ci|travis|circleci)" | head -20

Repository: EduIDE/Docs

Length of output: 117


🏁 Script executed:

# Look for any linting scripts in package.json
cat package.json | grep -A 5 -B 5 "lint\|style"

Repository: EduIDE/Docs

Length of output: 37


🏁 Script executed:

cat .github/workflows/deploy.yml

Repository: EduIDE/Docs

Length of output: 1015


🏁 Script executed:

cat package.json

Repository: EduIDE/Docs

Length of output: 1305


Replace invalid :not() syntax with valid complex notation to satisfy stylelint.

Lines 33 and 38 use chained simple :not() selectors, which violates the configured selector-not-notation: complex rule (inherited from stylelint-config-standard-scss).

The proposed syntax :not(##_) is invalid CSS. The :not() pseudo-class requires comma-separated selectors per CSS Selectors Level 4. Use :not(#) instead, noting this reduces specificity from 0,2,1 to 0,1,1:

Corrected fix
-[data-theme='dark'] .button.button--secondary:not(`#_`):not(`#_`) {
+[data-theme='dark'] .button.button--secondary:not(`#_`) {
   background-color: rgba(255, 255, 255, 0.08);
   color: `#e2e8f0`;
 }

-[data-theme='dark'] .button.button--secondary:not(`#_`):not(`#_`):hover {
+[data-theme='dark'] .button.button--secondary:not(`#_`):hover {
   background-color: rgba(255, 255, 255, 0.14);
   color: `#e2e8f0`;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[data-theme='dark'] .button.button--secondary:not(#_):not(#_) {
background-color: rgba(255, 255, 255, 0.08);
color: #e2e8f0;
}
[data-theme='dark'] .button.button--secondary:not(#_):not(#_):hover {
background-color: rgba(255, 255, 255, 0.14);
color: #e2e8f0;
[data-theme='dark'] .button.button--secondary:not(`#_`) {
background-color: rgba(255, 255, 255, 0.08);
color: `#e2e8f0`;
}
[data-theme='dark'] .button.button--secondary:not(`#_`):hover {
background-color: rgba(255, 255, 255, 0.14);
color: `#e2e8f0`;
}
🧰 Tools
🪛 Stylelint (17.4.0)

[error] 33-33: Expected complex :not() pseudo-class notation (selector-not-notation)

(selector-not-notation)


[error] 38-38: Expected complex :not() pseudo-class notation (selector-not-notation)

(selector-not-notation)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/css/custom.css` around lines 33 - 40, The selectors using chained :not()
like "[data-theme='dark'] .button.button--secondary:not(`#_`):not(`#_`)" violate the
selector-not-notation rule; replace the chained :not() instances with a single
complex :not() that lists the excluded selectors as a comma-separated list or,
for this case, simply use one :not(`#_`) to satisfy stylelint (update both the
normal and :hover selectors for ".button.button--secondary" under
[data-theme='dark'] so they become "[data-theme='dark']
.button.button--secondary:not(`#_`)" and the hover variant accordingly).

}
64 changes: 64 additions & 0 deletions src/pages/imprint.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,70 @@
}
}

[data-theme='dark'] .page {
background:
radial-gradient(circle at top left, rgba(15, 99, 255, 0.18), transparent 28%),
radial-gradient(circle at top right, rgba(10, 184, 126, 0.12), transparent 24%),
linear-gradient(180deg, #1e1e2e 0%, #1a1a2e 54%, #2a2a40 100%);
}

[data-theme='dark'] .heroCard,
[data-theme='dark'] .infoCard,
[data-theme='dark'] .sectionCard {
border-color: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.06);
box-shadow: 0 20px 45px rgba(0, 0, 0, 0.3);
}

[data-theme='dark'] .eyebrow {
color: #8bb4ff;
}

[data-theme='dark'] .heroCard h1 {
color: #e2e8f0;
}

[data-theme='dark'] .heroLead {
color: #94a3b8;
}

[data-theme='dark'] .secondaryAction {
border-color: rgba(255, 255, 255, 0.12);
color: #e2e8f0;
}

[data-theme='dark'] .infoLabel {
color: #94a3b8;
}

[data-theme='dark'] .infoCard strong {
color: #e2e8f0;
}

[data-theme='dark'] .infoCard p {
color: #94a3b8;
}

[data-theme='dark'] .sectionCard h2 {
color: #e2e8f0;
}

[data-theme='dark'] .sectionCard h3 {
color: #e2e8f0;
}

[data-theme='dark'] .sectionCard p {
color: #94a3b8;
}

[data-theme='dark'] .detailRow dt {
color: #94a3b8;
}

[data-theme='dark'] .detailRow dd {
color: #e2e8f0;
}

@media (max-width: 640px) {
.actions {
flex-direction: column;
Expand Down
7 changes: 0 additions & 7 deletions src/pages/imprint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ export default function Imprint() {
<strong>Technical University of Munich</strong>
<p>Arcisstrasse 21, 80333 Munich</p>
</div>
<div>
<span className={styles.infoLabel}>
Responsible for content
</span>
<strong>Prof. Dr. Stephan Krusche</strong>
<p>Boltzmannstrasse 3, 85748 Garching</p>
</div>
<div>
<span className={styles.infoLabel}>Applies to</span>
<strong>EduIDE Docs</strong>
Expand Down
71 changes: 71 additions & 0 deletions src/pages/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,77 @@
}
}

[data-theme='dark'] .page {
background:
radial-gradient(circle at top left, rgba(15, 99, 255, 0.18), transparent 28%),
radial-gradient(circle at top right, rgba(10, 184, 126, 0.12), transparent 24%),
linear-gradient(180deg, #1e1e2e 0%, #1a1a2e 54%, #2a2a40 100%);
}

[data-theme='dark'] .heroGlow {
background:
radial-gradient(circle at 20% 15%, rgba(30, 30, 46, 0.8), transparent 26%),
radial-gradient(circle at 75% 30%, rgba(73, 123, 255, 0.12), transparent 22%);
}

[data-theme='dark'] .kicker {
color: #8bb4ff;
}

[data-theme='dark'] .heroContent h1 {
color: #e2e8f0;
}

[data-theme='dark'] .lead {
color: #94a3b8;
}

[data-theme='dark'] .secondaryAction {
border-color: rgba(255, 255, 255, 0.12);
color: #e2e8f0;
}

[data-theme='dark'] .metricCard {
border-color: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.06);
box-shadow: 0 20px 45px rgba(0, 0, 0, 0.3);
}

[data-theme='dark'] .metricCard span {
color: #94a3b8;
}

[data-theme='dark'] .metricCard strong {
color: #e2e8f0;
}

[data-theme='dark'] .sectionCard {
border-color: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.06);
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.3);
}

[data-theme='dark'] .sectionCard:hover {
border-color: rgba(139, 180, 255, 0.4);
box-shadow: 0 24px 55px rgba(139, 180, 255, 0.1);
}

[data-theme='dark'] .sectionLabel {
color: #8bb4ff;
}

[data-theme='dark'] .sectionCard h2 {
color: #e2e8f0;
}

[data-theme='dark'] .sectionCard p {
color: #94a3b8;
}

[data-theme='dark'] .sectionCta {
color: #e2e8f0;
}

@media (max-width: 640px) {
.actions {
flex-direction: column;
Expand Down
16 changes: 8 additions & 8 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import Link from '@docusaurus/Link';
import styles from './index.module.css';

const sections = [
{
title: 'Developer',
description: 'API references, architecture decisions, integration guides, and implementation patterns.',
href: '/developer/intro',
},
{
title: 'Instructor',
description: 'Course delivery workflows, classroom playbooks, and content operations guidance.',
href: '/instructor/intro',
},
{
title: 'Student',
description: 'Onboarding, workspace basics, assignment flow, and submission support.',
href: '/student/intro',
},
{
title: 'Admins',
description: 'Provisioning, permissions, platform operations, and incident handling documentation.',
href: '/admins/intro',
},
{
title: 'Student',
description: 'Onboarding, workspace basics, assignment flow, and submission support.',
href: '/student/intro',
title: 'Developer',
description: 'API references, architecture decisions, integration guides, and implementation patterns.',
href: '/developer/intro',
},
];

Expand Down
Loading