Skip to content

Revive project changes#106

Merged
erikreinert merged 15 commits intomainfrom
feature/project-revive
Jul 17, 2025
Merged

Revive project changes#106
erikreinert merged 15 commits intomainfrom
feature/project-revive

Conversation

@erikreinert
Copy link
Contributor

@erikreinert erikreinert commented Jul 16, 2025

Overview

This PR implements a comprehensive version tagging system and adds multi-architecture build support to all LSP containers.

Key Changes

🏷️ Version Tagging System

  • Added ARG VERSION and LABEL version to all Dockerfiles
  • Updated GitHub Actions to extract versions and tag images as both latest and specific versions (e.g., gopls:0.19.1)
  • Converted hardcoded versions to use ${VERSION} variables in install commands

🏗️ Multi-Architecture Support

  • Added linux/amd64 and linux/arm64 build support
  • PowerShell ES builds only for amd64 due to Microsoft base image limitations
  • All other containers build for both architectures

📚 Documentation Updates

  • Added version badges to language server table in README
  • Updated contribution guidelines with versioning instructions
  • Removed references to nightly builds (no longer needed with static versioning)

🔧 CI/CD Improvements

  • Fixed version extraction logic in GitHub Actions
  • Added debugging output for build tags and platforms
  • Removed scheduled nightly builds (replaced with change-based builds)

Impact

  • Reproducible builds: All package versions are now pinned
  • Better user experience: Users can pin to specific language server versions
  • Broader platform support: ARM64 support for Apple Silicon and ARM servers
  • Efficient CI: Builds only trigger on actual changes

Container Updates

  • Updated all 28 language server containers with version standardization and multi-arch support.

Updated 26 Dockerfiles from dynamic tags to static versions:
- 22 Alpine images: alpine -> alpine:3.22.1
- 2 Debian images: debian -> debian:12.11-slim
- 1 Rust image: rustlang/rust:nightly -> rust:1.88.0-alpine3.22
- 1 Deno image: denoland/deno:alpine -> denoland/deno:alpine-2.4.2
- 1 PowerShell image: mcr.microsoft.com/powershell:alpine -> mcr.microsoft.com/powershell:7.5-alpine-3.20

This improves build reproducibility and security by pinning to specific versions.
Update all Dockerfiles to use explicit package versions for:
- Alpine packages (apk): nodejs, npm, yarn, git, python3, etc.
- Debian packages (apt): curl, ca-certificates, unzip
- npm packages: language servers and dependencies
- Ruby gems: solargraph
- Go packages: gopls tools and dependencies

This ensures reproducible builds by preventing version drift
and eliminates package version conflicts during container builds.
- Add -o flag to unzip commands to overwrite files without prompting
- Update terraform-ls to version 0.36.5 (was 0.36.0)
- Update terraform to version 1.12.2 (was 1.10.0)

This fixes the build failure caused by LICENSE.txt file conflicts
when extracting both terraform-ls and terraform archives.
- Update PowerShell Editor Services from v3.26.0 to v4.3.0
- Remove deprecated version field from docker-compose.yaml

The previous version v3.26.0 was not available, causing download
failures. Updated to the latest stable release v4.3.0.
- Update gopkgs from v2.3.0 to v2.1.2 (latest tagged release)
- Update go-outline to specific commit hash (no tagged releases)
- Update gotests from v1.6.3 to v1.6.0 (latest tagged release)
- Update impl to v1.4.0 (latest tagged release)
- Update delve from v1.24.2 to v1.25.0 (latest tagged release)
- Update staticcheck from 2024.1.1 to 2025.1.1 (latest tagged release)
- Update gopls from v0.17.0 to v0.19.1 (latest tagged release)

This fixes build failures caused by invalid version references
and ensures all Go development tools are at their latest stable versions.
- Add comprehensive project overview with clear value proposition
- Include professional badges for Docker Hub, build status, and license
- Create detailed language server table with version badges
- Add step-by-step contribution guide with code examples
- Include usage examples for VS Code, Neovim, and CI/CD integration
- Highlight architecture benefits (reproducible builds, security, automation)
- Add development workflow instructions and project statistics
- Transform from technical reference to welcoming community guide

This makes the project more accessible and appealing to potential
contributors while clearly communicating its value to developers.
- Update description to emphasize containers are for lspcontainers.nvim plugin
- Replace detailed setup instructions with link to plugin documentation
- Simplify Quick Start section to direct users to plugin repo
- Remove duplicate usage examples, point to plugin docs instead
- Add complete language server table (27 servers) without version badges
- Streamline content to avoid duplication between repositories
- Better separation of concerns: containers here, usage in plugin repo

This creates a cleaner user experience with single source of truth
for setup instructions while keeping focus on container development.
- Add ARG VERSION and LABEL version to all Dockerfiles
- Update GitHub Actions to extract version from ARG VERSION line
- Add debugging output to show exact tags used in builds
- Convert hardcoded versions to use ${VERSION} variables
- Update README.md with Dockerfile versioning documentation

Each Docker image now gets tagged with both 'latest' and the specific
language server version (e.g., gopls:latest and gopls:0.19.1).
- Add Version column to supported language servers table
- Show current language server versions from Dockerfiles
- Use shields.io badges for consistent visual styling
- Help users identify specific versions available in containers
- Add linux/amd64 and linux/arm64 platform support to Docker Buildx
- Configure build-push-action to build for both architectures
- Enables ARM64 support for Apple Silicon and ARM-based servers
- Maintains backward compatibility with existing amd64 deployments
- Add dynamic platform selection for containers with architecture limitations
- PowerShell ES builds only for linux/amd64 due to Microsoft base image constraints
- All other containers continue to build for linux/amd64,linux/arm64
- Add clear logging to show which platforms are being built for each container

This resolves the ARM64 build failure for powershell_es while maintaining
multi-architecture support for all other language server containers.
- Remove daily cron schedule from GitHub Actions workflow
- Update README to remove references to automated daily builds
- Builds now only trigger on pull requests and pushes to main
- Makes sense with static versioning where builds are only needed for changes

Static versioning eliminates the need for nightly rebuilds of identical versions.
@erikreinert erikreinert self-assigned this Jul 17, 2025
@erikreinert erikreinert added the enhancement New feature or request label Jul 17, 2025
@erikreinert erikreinert merged commit 94ed298 into main Jul 17, 2025
26 checks passed
@erikreinert erikreinert deleted the feature/project-revive branch July 17, 2025 22:32
Comment on lines 6 to 11
RUN apk add --no-cache \
build-base \
python3 \
python3-dev \
py3-pip \
build-base=0.5-r3 \
python3=3.12.11-r0 \
python3-dev=3.12.11-r0 \
py3-pip=25.1.1-r0 \
&& python3 -m venv /venv
Copy link
Contributor

Choose a reason for hiding this comment

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

Old packages are not kept in mirrors indefinitely. Once Python is upgraded (e.g.: to 3.12.12), this will break.

I assume you're pinning versions to ensure that distribution upgrade don't break builds. This really isn't necessary: Alpine 3.22 won't upgrade Python to an incompatible version (e.g.: to 3.12), so you don't need to pin packages like this.

I'm using python3 as an example, but the same applies to all other packages.

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand that you're pinning dependencies in order to achieve reproducible builds. Reproducible builds make sense in the context of distribution packages, but are much trickier when it comes to docker.

Distributions will update packages (typically, to a compatible release of the same major version) and don't usually retain older versions (since consumers aren't supposed to use old versions like this). Pinning the exact patch version of dependencies opts out of any security updates that upstream might roll out.

If you really want to pin the exact versions of the entire dependency tree, you need to use something like Gentoo. But I'd suggests not pinning as aggressively. Images are still reproducible until Alpine upgrade some dependency, at which point the new image is reproducible too.


### Building Containers Locally

```bash
Copy link
Contributor

Choose a reason for hiding this comment

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

Pedantic: Use sh here: the following script is regular shell script and doesn't require bash:

Suggested change
```bash
```sh

- **`latest`** - Latest build from main branch
- **`vX.Y.Z`** - Pinned version of the language server

```bash
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto:

Suggested change
```bash
```sh

Comment on lines 6 to 11
RUN apk add --no-cache \
build-base \
python3 \
python3-dev \
py3-pip \
build-base=0.5-r3 \
python3=3.12.11-r0 \
python3-dev=3.12.11-r0 \
py3-pip=25.1.1-r0 \
&& python3 -m venv /venv
Copy link
Contributor

Choose a reason for hiding this comment

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

I understand that you're pinning dependencies in order to achieve reproducible builds. Reproducible builds make sense in the context of distribution packages, but are much trickier when it comes to docker.

Distributions will update packages (typically, to a compatible release of the same major version) and don't usually retain older versions (since consumers aren't supposed to use old versions like this). Pinning the exact patch version of dependencies opts out of any security updates that upstream might roll out.

If you really want to pin the exact versions of the entire dependency tree, you need to use something like Gentoo. But I'd suggests not pinning as aggressively. Images are still reproducible until Alpine upgrade some dependency, at which point the new image is reproducible too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants