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
26 changes: 10 additions & 16 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,21 @@ updates:
schedule:
interval: "monthly"
open-pull-requests-limit: 1
labels: ["dependencies", "automated"]
commit-message:
prefix: "chore"
groups:
all-npm-dependencies:
patterns:
- "*"

- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 1
groups:
all-docker-dependencies:
patterns:
- "*"
npm-all:
patterns: ["*"]

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 1
labels: ["dependencies", "automated"]
commit-message:
prefix: "chore"
groups:
all-github-actions-dependencies:
patterns:
- "*"
github-actions-all:
patterns: ["*"]
23 changes: 23 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: PR Title

# Заголовок PR обязан быть conventional commit: при squash-мерже он становится
# сообщением коммита, а по нему release-please определяет разряд версии.
# Отдельные коммиты ветки намеренно не проверяются.
on:
pull_request_target:
types:
- opened
- edited
- synchronize
- reopened

permissions:
pull-requests: read

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 0 additions & 1 deletion .npmrc

This file was deleted.

24 changes: 24 additions & 0 deletions .oxfmtignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Что oxfmt не форматирует. Файл нужен потому, что без --ignore-path oxfmt читает
# .gitignore текущего каталога, а в ките в .gitignore лежат exercises/, courses/ и
# projects/ целиком: запущенный из корня oxfmt тогда молча пропускает весь контент,
# и это неотличимо от «всё уже отформатировано».
#
# Список повторяет ignorePatterns из .oxlintrc.json: линт и формат должны видеть
# одни и те же файлы.
node_modules/
# oxfmt форматирует не только js/ts: на spec.yml упражнения он снимает пустую
# строку, а package.json переписывает в свой вид. YAML и JSON в ките ведут другие
# инструменты (yamlfmt через mdsf, npm сам), поэтому здесь только js/ts.
*.yml
*.yaml
*.json
*.jsonc
*.css
*.md
npm-cache/
vendor/
dist/
build/
coverage/
.venv/
__snapshots__/
36 changes: 36 additions & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
"plugins": [
"typescript",
"unicorn",
"oxc",
"import",
"promise",
"node",
"jsdoc",
"vitest",
"react",
"react-perf",
"jsx-a11y",
"vue"
],
"categories": {
"correctness": "error"
},
"rules": {},
"env": {
"builtin": true,
"browser": true,
"node": true
},
"ignorePatterns": [
"**/node_modules/**",
"**/npm-cache/**",
"**/vendor/**",
"**/dist/**",
"**/build/**",
"**/coverage/**",
"**/.venv/**",
"**/__snapshots__/**"
]
}
16 changes: 13 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@ FROM node:26-slim

ENV PATH="$PATH:node_modules/.bin"

RUN apt-get update && apt-get install -y make
# make нужен, потому что команды приложения живут в Makefile.
RUN apt-get update && apt-get install -y --no-install-recommends make \
&& rm -rf /var/lib/apt/lists/*

# corepack из образов Node 26 убран, поэтому pnpm ставится напрямую. Версия
# берётся из поля packageManager, чтобы образ и разработка совпадали.
RUN npm install -g pnpm@11.20.0

WORKDIR /app

COPY package*.json ./
RUN npm ci
# Зависимости ставятся до копирования кода, чтобы слой с ними переиспользовался
# и не пересобирался на каждую правку исходников.
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

COPY . .

# Запуск через скрипт, а не через `pnpm start`: приложение слушает 3000, и на
# этот порт рассчитаны уроки курса docker_basics_course.
CMD ["bin/start.sh"]
13 changes: 7 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,23 @@ docker-push:
setup: env-prepare install

install:
npm ci
pnpm install --frozen-lockfile

start:
npm start
pnpm start

lint:
npx biome check .
pnpm --silent run lint
pnpm --silent run format:check

lint-fix:
npx biome check --write .
pnpm --silent run lint:fix

update-deps:
npx ncu -u
pnpm exec ncu -u

test:
npm test
pnpm test

env-prepare:
cp -n .env.example .env || true
Expand Down
16 changes: 8 additions & 8 deletions __tests__/error.test.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import fastify from 'fastify';
import fastify from "fastify";

import init from '../server/plugin.js';
import init from "../server/plugin.js";

describe('app', () => {
describe("app", () => {
let app;

beforeAll(async () => {
app = fastify();
await init(app);
});

it('error page', async () => {
it("error page", async () => {
const res = await app.inject({
method: 'GET',
url: '/error',
method: "GET",
url: "/error",
});

expect(res.body).toMatch('Внимание, тут что-то не так!');
expect(res.body).toMatch('Oops! Something went wrong!');
expect(res.body).toMatch("Внимание, тут что-то не так!");
expect(res.body).toMatch("Oops! Something went wrong!");
});
});
32 changes: 15 additions & 17 deletions __tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@
import fastify from 'fastify';
import _ from 'lodash';
import fastify from "fastify";
import _ from "lodash";

import init from '../server/plugin.js';
import init from "../server/plugin.js";

describe('app', () => {
describe("app", () => {
let app;

beforeAll(async () => {
app = fastify();
await init(app);
});

it('main page without environment variable SERVER_MESSAGE', async () => {
_.unset(process.env, 'SERVER_MESSAGE');
it("main page without environment variable SERVER_MESSAGE", async () => {
_.unset(process.env, "SERVER_MESSAGE");
const res = await app.inject({
method: 'GET',
url: '/',
method: "GET",
url: "/",
});

expect(res.statusCode).toBe(200);
expect(res.body).toMatch('Привет от Хекслета!');
expect(res.body).toMatch(
'Приложение запущено, но сообщение сервера не установлено!',
);
expect(res.body).toMatch("Привет от Хекслета!");
expect(res.body).toMatch("Приложение запущено, но сообщение сервера не установлено!");
});

it('main page with environment variable SERVER_MESSAGE', async () => {
process.env.SERVER_MESSAGE = 'Hexlet Awesome Server';
it("main page with environment variable SERVER_MESSAGE", async () => {
process.env.SERVER_MESSAGE = "Hexlet Awesome Server";

const res = await app.inject({
method: 'GET',
url: '/',
method: "GET",
url: "/",
});

expect(res.statusCode).toBe(200);
expect(res.body).toMatch('Привет от Хекслета!');
expect(res.body).toMatch("Привет от Хекслета!");
expect(res.body).toMatch(
`Приложение запущено и передает сообщение: ${process.env.SERVER_MESSAGE}`,
);
Expand Down
33 changes: 0 additions & 33 deletions biome.json

This file was deleted.

2 changes: 1 addition & 1 deletion instrument.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as Sentry from '@sentry/node';
import * as Sentry from "@sentry/node";

if (process.env.SENTRY_DSN) {
Sentry.init({ dsn: process.env.SENTRY_DSN });
Expand Down
Loading
Loading