README.md (4523B)
1 # Example 07 — Secrets with SOPS + Telegram 2 3 This Jaypore CI example shows how to keep secrets (API tokens, credentials) 4 encrypted inside your repository using [Mozilla SOPS](https://github.com/getsops/sops) 5 and decrypt them at CI time. The decrypted values are used to send a Telegram 6 notification with the build result. 7 8 ## How it works 9 10 | Step | What happens | 11 |------|-------------| 12 | 1 | If `sops` is installed and `secrets.enc.json` exists, decrypt it to obtain `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID`. | 13 | 2 | If SOPS is unavailable, fall back to plain environment variables. | 14 | 3 | Run `python3 manage.py test core` and capture the result. | 15 | 4 | Send a Markdown-formatted message to Telegram with the build status. | 16 | 5 | Save all artifacts to `$JCI_OUTPUT_DIR`. | 17 18 ## Artifacts produced 19 20 | File | Description | 21 |------|-------------| 22 | `test_output.txt` | Full test output. | 23 | `exit_code.txt` | Exit code from the test run. | 24 | `telegram_response.json` | Telegram API response (when notification is sent). | 25 26 ## Setting up SOPS 27 28 ### 1. Install SOPS 29 30 ```bash 31 # Debian / Ubuntu 32 curl -LO https://github.com/getsops/sops/releases/download/v3.9.4/sops_3.9.4_amd64.deb 33 sudo dpkg -i sops_3.9.4_amd64.deb 34 35 # macOS 36 brew install sops 37 ``` 38 39 ### 2. Choose an encryption backend 40 41 SOPS supports **age**, **GPG**, **AWS KMS**, **GCP KMS**, and **Azure Key Vault**. 42 For local / small-team use, [age](https://github.com/FiloSottile/age) is the 43 simplest option: 44 45 ```bash 46 # Install age 47 sudo apt install age # Debian/Ubuntu 48 brew install age # macOS 49 50 # Generate a key pair 51 age-keygen -o ~/.config/sops/age/keys.txt 52 # Note the public key printed to stdout (starts with "age1...") 53 ``` 54 55 ### 3. Create a `.sops.yaml` config (optional but recommended) 56 57 Place this in your repository root so SOPS knows which key to use: 58 59 ```yaml 60 creation_rules: 61 - path_regex: secrets\.enc\.json$ 62 age: "age1your-public-key-here" 63 ``` 64 65 ### 4. Create and encrypt the secrets file 66 67 Start from the provided template: 68 69 ```bash 70 cp secrets.example.json secrets.json 71 ``` 72 73 Edit `secrets.json` with your real values: 74 75 ```json 76 { 77 "TELEGRAM_BOT_TOKEN": "123456789:ABCdefGHI-JKLmnoPQRstUVwxyz", 78 "TELEGRAM_CHAT_ID": "-1001234567890" 79 } 80 ``` 81 82 Encrypt it: 83 84 ```bash 85 sops -e secrets.json > secrets.enc.json 86 ``` 87 88 Now commit `secrets.enc.json` (the encrypted version) and **delete the 89 plaintext** `secrets.json`: 90 91 ```bash 92 rm secrets.json 93 git add secrets.enc.json 94 git commit -m "Add encrypted secrets" 95 ``` 96 97 > **Never commit the plaintext `secrets.json`.** Add it to `.gitignore`. 98 99 ### 5. Decrypt (what run.sh does) 100 101 At CI time the script runs: 102 103 ```bash 104 sops -d secrets.enc.json 105 ``` 106 107 This prints the decrypted JSON to stdout. The script parses it with Python to 108 extract individual values into environment variables. 109 110 Decryption requires the private key. For `age`, the key file at 111 `~/.config/sops/age/keys.txt` is used automatically. 112 113 ## Alternative: plain environment variables 114 115 If you prefer not to use SOPS, export the variables before running CI: 116 117 ```bash 118 export TELEGRAM_BOT_TOKEN="123456789:ABCdefGHI-JKLmnoPQRstUVwxyz" 119 export TELEGRAM_CHAT_ID="-1001234567890" 120 git jci run 121 ``` 122 123 The script detects that SOPS is absent (or that the encrypted file is missing) 124 and falls back to whatever `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` are 125 already set in the environment. 126 127 ## Setting up Telegram 128 129 1. Create a bot via [BotFather](https://t.me/BotFather) and note the **bot 130 token**. 131 2. Get your **chat ID** by sending a message to the bot and visiting 132 `https://api.telegram.org/bot<TOKEN>/getUpdates`. 133 3. Put both values into `secrets.json` and encrypt with SOPS (see above), or 134 export them as environment variables. 135 136 ## Project layout 137 138 ``` 139 your-repo/ 140 ├── manage.py 141 ├── mysite/ 142 │ └── settings.py 143 ├── core/ # the Django app under test 144 ├── secrets.enc.json # encrypted secrets (committed) 145 ├── secrets.example.json # template with placeholder values 146 ├── .sops.yaml # SOPS config (optional) 147 └── .jci/ 148 └── run.sh # ← this script 149 ``` 150 151 ## How to use 152 153 1. Copy the `.jci/` directory and `secrets.example.json` into your repo: 154 155 ```bash 156 cp -r 07-secrets-telegram/.jci /path/to/your-repo/.jci 157 cp 07-secrets-telegram/secrets.example.json /path/to/your-repo/ 158 ``` 159 160 2. Set up SOPS and encrypt your secrets (see above), or export them as 161 environment variables. 162 163 3. Run Jaypore CI: 164 165 ```bash 166 git jci run 167 ```