Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move from asdf to Dev Container #202

Merged
merged 5 commits into from
May 16, 2024
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
21 changes: 21 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Creates development machine inside docker
# so every developer will have the same environment

FROM node:22.1.0-alpine

RUN apk update \
&& apk add --no-cache zsh git eza tig ripgrep bat curl micro starship \
&& rm -rf /var/cache/apk/*
RUN npm install -g [email protected]
RUN sed -i 's|/node:/bin/sh|/node:/bin/zsh|' /etc/passwd

USER node

RUN pnpm config set store-dir /home/node/.local/share/pnpm/store \
&& pnpm config set ignore-scripts false

RUN micro -plugin install editorconfig
RUN mkdir -p /home/node/.config \
&& echo 'eval "$(starship init zsh)"' >> /home/node/.zshrc
RUN printf 'format = "$directory$git_branch$line_break$character"' \
> /home/node/.config/starship.toml
24 changes: 24 additions & 0 deletions .devcontainer/docker/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"build": {
"context": "..",
"dockerfile": "../Dockerfile"
},
"forwardPorts": [5173, 5284, 6006],
"customizations": {
"vscode": {
"extensions": [
"connor4312.nodejs-testing",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"svelte.svelte-vscode",
"webben.browserslist",
"yoavbls.pretty-ts-errors",
"streetsidesoftware.code-spell-checker",
"editorconfig.editorconfig",
"yzhang.markdown-all-in-one",
"davidlday.languagetool-linter"
]
}
}
}
41 changes: 41 additions & 0 deletions .devcontainer/podman/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"build": {
"context": "..",
"dockerfile": "../Dockerfile"
},
"forwardPorts": [5173, 5284, 6006],
"mounts": [
{
"source": "pnpm-store",
"target": "/home/node/.local/share/pnpm/store",
"type": "volume"
},
{
"source": "shell-history",
"target": "/home/node/.shell-history/",
"type": "volume"
}
],
"workspaceMount": "",
"runArgs": [
"--userns=keep-id:uid=1000,gid=1000",
"--volume=${localWorkspaceFolder}:/workspaces/${localWorkspaceFolderBasename}:Z"
],
"customizations": {
"vscode": {
"extensions": [
"connor4312.nodejs-testing",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"stylelint.vscode-stylelint",
"svelte.svelte-vscode",
"webben.browserslist",
"yoavbls.pretty-ts-errors",
"streetsidesoftware.code-spell-checker",
"editorconfig.editorconfig",
"yzhang.markdown-all-in-one",
"davidlday.languagetool-linter"
]
}
}
}
9 changes: 7 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ jobs:
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Install tools from asdf config
uses: ai/asdf-cache-action@v1
- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install dependencies
run: pnpm install --ignore-scripts
- name: Check docs
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ on:
- '**/*.md'
- '.vscode/**'
- '.husky/**'
- '.devcontainer/**'
pull_request:
paths-ignore:
- '**/*.md'
- '.vscode/**'
- '.husky/**'
- '.devcontainer/**'
jobs:
test:
name: Test
Expand All @@ -21,8 +23,13 @@ jobs:
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Install tools from asdf config
uses: ai/asdf-cache-action@v1
- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install dependencies
run: pnpm install --ignore-scripts
- name: Run tests
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/preview-prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install tools from asdf config
uses: ai/asdf-cache-action@v1
- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Allow to install only web dependencies
run: pnpm config set recursive-install false
- name: Install dependencies
Expand Down
18 changes: 13 additions & 5 deletions .github/workflows/proxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install tools from asdf config
uses: ai/asdf-cache-action@v1
- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install dependencies
run: pnpm install --ignore-scripts
- name: Run tests
Expand All @@ -38,10 +43,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install tools from asdf config
uses: ai/asdf-cache-action@v1
- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
dependencies-cache: proxy-production
node-version-file: .node-version
# We don’t use cache for supply chain security
- name: Allow to install only project dependencies
run: pnpm config set recursive-install false
- name: Install dependencies
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/test-loaders.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ jobs:
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Install tools from asdf config
uses: ai/asdf-cache-action@v1
- name: Install pnpm
uses: pnpm/action-setup@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install dependencies
run: pnpm install --ignore-scripts
- name: Loaders Test
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/visual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ jobs:
echo "has_commits=false" >> "$GITHUB_OUTPUT"
echo "No commits today. Stopping the workflow."
fi
- name: Install tools from asdf config
- name: Install pnpm
if: steps.today.outputs.has_commits == 'true'
uses: ai/asdf-cache-action@v1
uses: pnpm/action-setup@v3
- name: Install Node.js
if: steps.today.outputs.has_commits == 'true'
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install dependencies
if: steps.today.outputs.has_commits == 'true'
run: pnpm install --ignore-scripts
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/

1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.1.0
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
coverage/
dist/
web/storybook-static/
5 changes: 0 additions & 5 deletions .tool-versions

This file was deleted.

3 changes: 3 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["ms-vscode-remote.remote-containers"]
}
16 changes: 6 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,15 @@ You can ask any question to the maintainer in Telegram: **[`@sitnik`](https://t.

1. Install environment:

- To fix a small bug you can run app directly in your browser via [StackBlitz](https://stackblitz.com/fork/github/hplush/slowreader?file=web/main/main.svelte).
- To fix a small bug, you can run the app directly in your browser via [StackBlitz](https://stackblitz.com/fork/github/hplush/slowreader?file=web/main/main.svelte).

- For lond-term contribution we recommend installing [`asdf`](https://asdf-vm.com/guide/getting-started.html) and then run:
- For lond-term contribution, we recommend installing Docker and [Dev Container](https://containers.dev) plugin to your text editor. All developers will have the same environment and the development tool will be isolated from the system in the container.

```sh
asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs.git
asdf plugin-add pnpm https://github.com/jonathanmorley/asdf-pnpm.git
asdf install
```
- [VS Code guide](https://code.visualstudio.com/docs/devcontainers/tutorial)
- [Jet Brains IDEs](https://www.jetbrains.com/help/idea/connect-to-devcontainer.html#create_dev_container_inside_ide)
- [CLI tool](https://github.com/devcontainers/cli)

- You can also manually install [Node.js](https://nodejs.org/en/download) and [pnpm](https://pnpm.io/installation) versions according to [`.tool-versions`](./.tool-versions) file.
- You can also manually install [Node.js](https://nodejs.org/en/download) and [pnpm](https://pnpm.io/installation) versions according to `.node-version` file and `packageManager` key in `package.json`.

2. Then install all npm dependencies by `pnpm`:

Expand All @@ -68,8 +66,6 @@ You can ask any question to the maintainer in Telegram: **[`@sitnik`](https://t.
pnpm test
```

If you have strange error, check that all folders in the path to the project use **only Latin symbols**.

### Run Web Client

To run web clients, just call in the root of the project:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ Slow Reader is a local-first app. Clients do most of the work, and the server ju
- [`docs/`](./docs/): guides for developers.
- [`scripts/`](./scripts/): scripts to test project and configure Google Cloud. Check the script’s descriptions for further details.
- [`loader-tests/`](./loader-tests/): integration tests for each social network or news format.
- [`.devcontainer`](./.devcontainer/): `Dockerfile` and configs to run project in Docker/Podman image on developer’s machine. It increases security (malicious dependency will not have access to the whole machine) and simplify onboarding.
- [`.github/`](./.github/): scripts to test projects on CI.
- [`.husky/`](./.husky/): scripts to call on `git commit` command to avoid popular errors.
- [`.vscode/`](./.vscode/): VS Code settings to reduce code format errors for new contributors.
Expand All @@ -118,7 +119,7 @@ We are using [pnpm monorepo](https://pnpm.io/workspaces). Each project has its d

Global development tools:

- [asdf](./.tool-versions) to synchronize Node.js and pnpm versions across the team and CI.
- [Dev Container](https://containers.dev) to use the same environment for all developers and isolate project from developer’s machine.
- [Prettier](./.prettierrc) to use the same code style formatting.
- [TypeScript](./tsconfig.json) for strict type checking.
- [ESLint](./eslint.config.js) to check for popular mistakes in JavaScript.
Expand Down
3 changes: 2 additions & 1 deletion nano-staged.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"*.css": "stylelint --fix",
"*.svelte": ["prettier --write", "stylelint --fix"],
"*.svg": "svgo",
".tool-versions": "tsx ./scripts/check-versions.ts",
".devcontainer/Dockerfile": "tsx ./scripts/check-versions.ts",
".node-version": "tsx ./scripts/check-versions.ts",
"package.json": "tsx ./scripts/check-versions.ts",
"*/package.json": "tsx ./scripts/check-versions.ts",
"*/Dockerfile": "tsx ./scripts/check-versions.ts",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"node": "^22.1.0",
"pnpm": "^9.0.0"
},
"packageManager": "[email protected]",
"scripts": {
"test": "FORCE_COLOR=1 pnpm run -r --include-workspace-root /^test:/",
"start": "FORCE_COLOR=1 pnpm run -r start",
Expand Down
42 changes: 29 additions & 13 deletions scripts/check-versions.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
// Script to check that:
// - All dependencies has "1.2.3" requirement and not "^1.2.3" used by npm.
// It prevents unexpected updates on lock file issues.
// - Node.js and pnpm versions in .tool-versions and package.json are the same.
// - All Dockerfile use the same Node.js version that is in .tool-versions.
// - Node.js and pnpm versions are the same in all configs
// (Dockerfile, package.json, .node-version).

import { existsSync, readdirSync, readFileSync } from 'node:fs'
import { join } from 'node:path'
import { styleText } from 'node:util'

const ROOT = join(import.meta.dirname, '..')

function read(...parts: string[]): string {
return readFileSync(join(ROOT, ...parts)).toString()
function read(file: string): string {
return readFileSync(join(ROOT, file)).toString()
}

function error(msg: string): void {
process.stderr.write(styleText('red', `${msg}\n`))
process.exit(1)
}

let toolVersions = read('.tool-versions')
function getVersion(content: string, regexp: RegExp): string {
return content.match(regexp)![1]!
}

let dockerfile = read('.devcontainer/Dockerfile')

let nodeFull = toolVersions.match(/nodejs (\d+\.\d+\.\d+)/)![1]
let nodeMinor = toolVersions.match(/nodejs (\d+\.\d+)\./)![1]
let pnpmMajor = toolVersions.match(/pnpm (\d+)\./)![1]
let nodeFull = getVersion(dockerfile, /node:(\d+\.\d+\.\d+)/)
let nodeMinor = nodeFull.split('.').slice(0, 2).join('.')
let pnpmFull = getVersion(dockerfile, /pnpm@(\d+\.\d+\.\d+)/)
let pnpmMajor = pnpmFull.split('.')[0]

function checkPackage(file: string, content: string): void {
if (!content.includes(`"node": "^${nodeMinor}.`)) {
error(`.tool-versions and ${file} have different Node.js minor version`)
error(`.devcontainer/Dockerfile and ${file} have different Node.js version`)
}
if (!content.includes(`"pnpm": "^${pnpmMajor}.`)) {
error(`.tool-versions and ${file} have different pnpm major version`)
error(`.devcontainer/Dockerfile and ${file} have different pnpm version`)
}
let match = content.match(/"[^"]+": "[\^~][^"]+"/)
if (match && !match[0].startsWith('"node":')) {
Expand All @@ -50,17 +55,28 @@ function checkDockerfile(file: string, content: string): void {
}
}

let nodeVersion = read('.node-version').trim()
if (nodeVersion !== nodeFull) {
error(
'.devcontainer/Dockerfile and .node-version have different Node.js version'
)
}
let packageManager = getVersion(
read('package.json'),
/"packageManager": "pnpm@(\d+\.\d+\.\d+)"/
)
if (packageManager !== pnpmFull) {
error('.devcontainer/Dockerfile and package.json have different pnpm version')
}

checkPackage('package.json', read('package.json'))

let projects = readdirSync(ROOT)

for (let project of projects) {
if (existsSync(join(ROOT, project, 'package.json'))) {
let relative = join(project, 'package.json')
checkPackage(relative, read(relative))
}
}
for (let project of projects) {
if (existsSync(join(ROOT, project, 'Dockerfile'))) {
let docker = join(project, 'Dockerfile')
checkDockerfile(docker, read(docker))
Expand Down