# Примеры

к сведению

Названия всех команд лишь для примера у вас вероятнее всего будет свой вариант.

## Локальная разработка

### 🍪 JavaScript (Vue, React, Angular и др.)

Практически любой web проект содержит `package.json` и в нём есть scripts, где описаны разные команды, для сборки, для запуска и отладки локально. Выглядит примерно так:

```json
...
  "scripts": {
    "serve": "vite",
...

```

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Установите конфигурацию для проекта `tuna secrets setup`.
3. Отредактируйте `package.json` и добавите обёртку `tuna secrets run`, должно получиться примерно так:

```json
...
  "scripts": {
    "serve": "tuna secrets run --watch -- vite",
...

```

4. Запустите приложение как обычно `yarn serve` или `npm run serve`

***

### 🐹 Go (Golang)

Go-проекты обычно запускаются через `go run` или `make`:

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Выполните `tuna secrets setup`.
3. Запустите приложение с обёрткой:

```shell
tuna secrets run --watch -- go run ./cmd/server

```

Пример Makefile:

```yaml
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
    @tuna secrets run --watch -- go run ./cmd/server

```

### 🦀 Rust (Rocket, Actix и др.)

Rust-проекты чаще всего используют cargo:

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Выполните `tuna secrets setup`.
3. Запустите приложение с обёрткой:

```shell
tuna secrets run --watch -- cargo run

```

Пример Makefile:

```yaml
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
    @tuna secrets run --watch -- cargo run

```

***

### 🥠 Node.js серверный проект (Express, Fastify и др.)

Node.js backend обычно также использует `package.json`, например:

```json
...
  "scripts": {
    "dev": "node server.js",
...

```

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Установите конфигурацию для проекта `tuna secrets setup`.
3. Отредактируйте `package.json`, добавив обёртку:

```json
...
  "scripts": {
    "dev": "tuna secrets run --watch -- node server.js",
...

```

4. Запустите приложение `yarn dev` или `npm run dev`.

***

### 🐍 Python (Flask, Django и др.)

Python-проекты часто запускаются через `python`, `manage.py` или `Makefile`.

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Установите конфигурацию для проекта добавив обёртку `tuna secrets setup`.
3. Оберните команду запуска:

```bash
tuna secrets run --watch -- python app.py

```

Если у вас Django:

```bash
tuna secrets run --watch -- python manage.py runserver

```

Если у вас Makefile:

```yaml
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
    @tuna secrets run --watch -- python manage.py runserver

```

4. Запустите приложение этой командой.

***

### 🐘 PHP (Laravel, Symfony и др.)

Обычно используется встроенный веб-сервер PHP:

```shell
php -S localhost:8000 -t public

```

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Установите конфигурацию для проекта `tuna secrets setup`.
3. Запустите сервер через обёртку `tuna secrets run`:

```bash
tuna secrets run --watch -- php -S localhost:8000 -t public

```

Если у вас Laravel:

```bash
tuna secrets run --watch -- php artisan serve

```

Пример Makefile:

```yaml
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
    @tuna secrets run --watch -- php artisan serve

```

***

### ☕ Java/Kotlin (Spring Boot, Micronaut и др.)

Такие проекты часто используют Gradle или Maven:

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Установите конфигурацию для проекта `tuna secrets setup`.
3. Оберните команду запуска:

Для Gradle:

```bash
tuna secrets run --watch -- ./gradlew bootRun

```

Для Maven:

```bash
tuna secrets run --watch -- mvn spring-boot:run

```

Пример Makefile:

```yaml
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
    @tuna secrets run --watch -- mvn spring-boot:run

```

4. Запустите приложение как обычно.

***

### 🪟 C#/.NET (ASP.NET Core и др.)

Проекты на .NET запускаются через `dotnet run`:

1. Перейдите в каталог с проектом `cd ~/path/to/your/project`.
2. Выполните `tuna secrets setup`.
3. Запустите приложение с обёрткой:

```shell
tuna secrets run --watch -- dotnet run

```

Пример Makefile (на Linux/macOS):

```yaml
.DEFAULT_GOAL := run
.PHONY: run
run: ### Запуск
    @tuna secrets run --watch -- dotnet run

```

***

## CI/CD

### 🦊 Gitlab CI

Создайте [сервисные ключи](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) для нужных конфигураций и сохраните ключ в [Gitlab ci variables](https://docs.gitlab.com/ci/variables/). Предположим, у вас есть проект `myproj` в нём есть окружение `prod`, создайте сервисный ключ и сохраните его в переменную `TUNA_API_KEY_MYPROJ_PROD` в Gitlab variables. Ниже пример того как это может выглядеть в Job:

**Переменные окружения**

```yaml
production:
  extends: [.base]
  environment:
    name: prod
  variables:
    TUNA_API_KEY: $TUNA_API_KEY_MYPROJ_PROD
    TUNA_SECRETS_PROJECT: $CI_PROJECT_NAME
    TUNA_SECRETS_CONFIG: $CI_ENVIRONMENT_NAME
    TUNA_SECRETS_FORMAT: env
    TUNA_SECRETS_NO_FILE: true
  before_script:
    - source <(tuna secrets download)
  script:
    - goreleaser release

```

**Флаги**

```yaml
production:
  extends: [.base]
  environment:
    name: prod
  before_script:
    - source <(tuna --api-key=${TUNA_API_KEY_MYPROJ_PROD} secrets download --project=${CI_PROJECT_NAME} --config=${CI_ENVIRONMENT_NAME} --format=env --no-file)
  script:
    - goreleaser release

```

**Обёртка run**

```yaml
production:
  extends: [.base]
  environment:
    name: prod
  variables:
    TUNA_API_KEY: $TUNA_API_KEY_MYPROJ_PROD
    TUNA_SECRETS_PROJECT: $CI_PROJECT_NAME
    TUNA_SECRETS_CONFIG: $CI_ENVIRONMENT_NAME
  script:
    - tuna secrets run -- goreleaser release

```

Секреты попадают только в окружение процесса: ни файла в рабочем каталоге, ни `source` в истории джобы. Код выхода `goreleaser` становится кодом выхода джобы.

Заметьте, что **project** и **config** мы получаем прямо из окружения, это возможно, если имя проекта в Gitlab и Tuna Secrets совпадают, а также environment.name в Gitlab Job соответствует алиасу конфигурации.

***

### 🐱 GitHub Actions

Создайте [сервисные ключи](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) для нужных конфигураций и сохраните ключ в [GitHub Secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions). Предположим, у вас есть проект `myproj` в нём есть окружение `prod`, создайте сервисный ключ и сохраните его в переменную `TUNA_API_KEY_MYPROJ_PROD` в GitHub Secrets. Ниже пример того как это может выглядеть в Job:

**Переменные окружения**

```yaml
name: Release

on:
  push:
    tags:
      - "v*"

jobs:
  production:
    runs-on: ubuntu-latest
    env:
      TUNA_API_KEY: ${{ secrets.TUNA_API_KEY_MYPROJ_PROD }}
      TUNA_SECRETS_PROJECT: ${{ github.event.repository.name }}
      TUNA_SECRETS_CONFIG: prod
      TUNA_SECRETS_FORMAT: env
      TUNA_SECRETS_NO_FILE: true
    steps:
      - uses: actions/checkout@v4
      - run: |
          source <(tuna secrets download)
          goreleaser release

```

**Флаги**

```yaml
name: Release

on:
  push:
    tags:
      - "v*"

jobs:
  production:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: |
          source <(tuna --api-key=${{ secrets.TUNA_API_KEY_MYPROJ_PROD }} secrets download --project=${{ github.event.repository.name }} --config=prod --format=env --no-file)
          goreleaser release


```

**Обёртка run**

```yaml
name: Release

on:
  push:
    tags:
      - "v*"

jobs:
  production:
    runs-on: ubuntu-latest
    env:
      TUNA_API_KEY: ${{ secrets.TUNA_API_KEY_MYPROJ_PROD }}
      TUNA_SECRETS_PROJECT: ${{ github.event.repository.name }}
      TUNA_SECRETS_CONFIG: prod
    steps:
      - uses: actions/checkout@v4
      - run: tuna secrets run -- goreleaser release

```

Заметьте, что `project = github.event.repository.name` мы получаем прямо из окружения, это возможно, если имя проекта в GitHub и Tuna Secrets совпадают, **config** - задаётся явно.

***

### 🧰 Отдельные секреты в скриптах

Когда джобе нужен один секрет, выгружать всю конфигурацию незачем. Флаг `--plain` печатает значение без перевода строки в конце, поэтому его удобно подставлять прямо в команду:

```yaml
publish:
  script:
    - docker login -u "$CI_REGISTRY_USER" -p "$(tuna secrets get REGISTRY_PASSWORD --plain)" "$CI_REGISTRY"

```

Флаг `-o json` есть у всех команд, включая запись, — это то, что нужно скриптам:

```yaml
rotate-token:
  script:
    - openssl rand -hex 32 | tuna secrets set API_TOKEN
    - tuna secrets get API_TOKEN -o json | jq -r '.API_TOKEN.updated_at'

```

Ротация требует сервисного ключа с доступом `write`.

А вот проверка, что в stage и prod не оказалось одинаковых паролей. Она работает с [отпечатками](https://tuna.am/docs/secrets/cli.md#%D0%BE%D1%82%D0%BF%D0%B5%D1%87%D0%B0%D1%82%D0%BA%D0%B8-%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9), а не со значениями, поэтому результат не страшно оставить в логе джобы:

```yaml
check-secrets:
  script:
    - tuna secrets list -c stage -o json | jq -r 'to_entries[] | "\(.key) \(.value.fingerprint)"' > stage.txt
    - tuna secrets list -c prod  -o json | jq -r 'to_entries[] | "\(.key) \(.value.fingerprint)"' > prod.txt
    - comm -12 stage.txt prod.txt

```

***

### 🧵 Bitbucket Pipelines

Создайте [сервисные ключи](https://tuna.am/docs/secrets.md#%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BB%D1%8E%D1%87%D0%B8) для нужных конфигураций и сохраните ключ в [Bitbucket Pipelines variables](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/). Предположим, у вас есть проект `myproj` в нём есть окружение `prod`, создайте сервисный ключ и сохраните его в переменную `TUNA_API_KEY_MYPROJ_PROD` в Bitbucket Pipelines variables. Ниже пример того как это может выглядеть в Job:

**Переменные окружения**

```yaml
pipelines:
  tags:
    "v*":
      - step:
          name: Production Build
          deployment: prod
          script:
            - export TUNA_API_KEY=$TUNA_API_KEY_MYPROJ_PROD
            - export TUNA_SECRETS_PROJECT=$BITBUCKET_REPO_SLUG
            - export TUNA_SECRETS_CONFIG=prod
            - export TUNA_SECRETS_FORMAT=env
            - export TUNA_SECRETS_NO_FILE=true
            - source <(tuna secrets download)
            - goreleaser release


```

**Флаги**

```yaml
pipelines:
  tags:
    "v*":
      - step:
          name: Release
          deployment: prod
          script:
            - source <(tuna --api-key=$TUNA_API_KEY_MYPROJ_PROD secrets download --project=$BITBUCKET_REPO_SLUG --config=prod) --format=env --no-file)
            - goreleaser release


```

Заметьте, что `project = $BITBUCKET_REPO_SLUG` мы получаем прямо из окружения, это возможно, если имя проекта в `BITBUCKET_REPO_SLUG` и Tuna Secrets совпадают, **config** - задаётся явно.
