Skip to content

Commit 1b8574d

Browse files
committed
feat: add initial Perl console application scaffolding
- Add TorrustDeploy::App main application module with App::Cmd framework - Add help command with proper metadata and infinite loop prevention - Add executable script with comprehensive comments - Add test suite with unit and integration tests - Add GitHub Actions workflow for testing and linting - Add .gitignore for Perl project artifacts - Add cpanfile with required dependencies - Add README with installation and usage instructions This provides the foundation for building a deployment tool for Torrust Tracker to Hetzner Cloud using Packer, Terraform, and Ansible.
0 parents  commit 1b8574d

File tree

16 files changed

+538
-0
lines changed

16 files changed

+538
-0
lines changed

.github/copilot-instructions.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Torrust Tracker Deployment Tool
2+
3+
A modern Perl console application for deploying Torrust Tracker to Hetzner Cloud using Packer, Terraform, and Ansible.
4+
5+
## Code Quality Standards
6+
7+
### Markdown Documentation
8+
9+
- **Linting**: Follow [markdownlint](https://github.com/DavidAnson/markdownlint) conventions
10+
- **Structure**: Use consistent heading hierarchy
11+
- **Links**: Prefer relative links for internal documentation
12+
- **Code blocks**: Always specify language for syntax highlighting
13+
- **Tables**: Tables automatically ignore line length limits (configured globally in
14+
`.markdownlint.json`). No special formatting required for table line lengths.
15+
16+
## Git
17+
18+
### Branch Naming
19+
20+
- **Format**: `{issue-number}-{short-description-following-github-conventions}`
21+
- **GitHub conventions**: Use lowercase, separate words with hyphens, descriptive but concise
22+
- **Examples**: `42-add-mysql-support`, `15-fix-ssl-renewal`, `24-improve-ux-add-automatic-waiting-to-infra-apply-and-app-deploy-commands`
23+
- Always start with the GitHub issue number
24+
- Follow GitHub's recommended branch naming: lowercase, hyphens for word separation, descriptive of the change
25+
26+
### Commit Messages
27+
28+
- **Format**: Conventional Commits with issue references
29+
- **Structure**: `{type}: [#{issue}] {description}`
30+
- **Examples**:
31+
```
32+
feat: [#42] add MySQL database support
33+
fix: [#15] resolve SSL certificate renewal issue
34+
docs: [#8] update deployment guide
35+
ci: [#23] add infrastructure validation tests
36+
```
37+
38+
### Commit Types
39+
40+
- `feat`: New features
41+
- `fix`: Bug fixes
42+
- `docs`: Documentation changes
43+
- `ci`: CI/CD pipeline changes
44+
- `refactor`: Code refactoring
45+
- `test`: Test additions/changes
46+
- `chore`: Maintenance tasks
47+
48+
### Git Actions and Permission Requirements
49+
50+
**IMPORTANT**: Git actions that change repository state require explicit permission:
51+
52+
- **NEVER** commit changes unless explicitly asked to do so
53+
- **NEVER** push changes to remote repositories without permission
54+
- **NEVER** merge branches or create pull requests without explicit instruction
55+
- **NEVER** reset, revert, or modify git history without explicit permission
56+
- **NEVER** create or delete branches without explicit instruction
57+
58+
**Allowed git actions without permission:**
59+
60+
- `git status` - Check working tree status
61+
- `git diff` - Show changes between commits/files
62+
- `git log` - View commit history
63+
- `git show` - Display commit information
64+
- `git branch` - List branches (read-only)
65+
66+
**Actions requiring explicit permission:**
67+
68+
- `git add` - Stage changes for commit
69+
- `git commit` - Create new commits
70+
- `git push` - Push changes to remote
71+
- `git pull` - Pull changes from remote
72+
- `git merge` - Merge branches
73+
- `git rebase` - Rebase branches
74+
- `git reset` - Reset working tree or commits
75+
- `git revert` - Revert commits
76+
- `git checkout` - Switch branches or restore files
77+
- `git branch -d/-D` - Delete branches
78+
- `git tag` - Create or delete tags
79+
80+
**Commit Signing Requirement**: All commits MUST be signed with GPG. When performing git commits, always use the default git commit behavior (which will trigger GPG signing) rather than `--no-gpg-sign`.
81+
82+
**Pre-commit Testing Requirement**:
83+
84+
ALWAYS run the tests suite before committing any changes:
85+
86+
```bash
87+
carmel exec -- prove -l t/
88+
```
89+
90+
ALWAYS run the linting suite before committing any changes:
91+
92+
```bash
93+
markdownlint "**/*.md"
94+
```

.github/workflows/testing.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Testing
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
name: Lint
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Install dependencies
19+
run: |
20+
sudo apt-get update
21+
sudo npm install -g markdownlint-cli
22+
23+
- name: Run linting
24+
run: markdownlint "**/*.md"
25+
26+
test:
27+
runs-on: ubuntu-latest
28+
name: Test
29+
30+
steps:
31+
- name: Checkout code
32+
uses: actions/checkout@v4
33+
34+
- name: Setup Perl
35+
uses: shogo82148/actions-setup-perl@v1
36+
with:
37+
perl-version: "5.20"
38+
39+
- name: Install cpanminus and Carmel
40+
run: |
41+
curl -L https://cpanmin.us | perl - App::cpanminus
42+
cpanm --local-lib=~/perl5 local::lib
43+
eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
44+
cpanm Carmel
45+
46+
- name: Install project dependencies
47+
run: |
48+
eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
49+
export PATH="$HOME/perl5/bin:$PATH"
50+
carmel install
51+
52+
- name: Run tests
53+
run: |
54+
eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
55+
export PATH="$HOME/perl5/bin:$PATH"
56+
carmel exec -- prove -l t/

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Carmel dependency management
2+
local/
3+
.carmel/
4+
cpanfile.snapshot
5+
6+
# Editor temporary files
7+
*.swp
8+
*.swo
9+
*~
10+
11+
# OS files
12+
.DS_Store
13+
Thumbs.db

.markdownlint.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"default": true,
3+
"MD013": {
4+
"line_length": 100,
5+
"tables": false
6+
},
7+
"MD031": true,
8+
"MD032": true,
9+
"MD040": true,
10+
"MD022": true,
11+
"MD009": true,
12+
"MD007": {
13+
"indent": 2
14+
},
15+
"MD026": false,
16+
"MD041": false,
17+
"MD034": false,
18+
"MD024": false,
19+
"MD033": false
20+
}

.markdownlint.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Markdownlint Configuration
2+
3+
This file documents the markdownlint configuration for the project.
4+
5+
## Line Length Handling
6+
7+
The project enforces a 100-character line limit for markdown files (`MD013` rule).
8+
Tables are automatically excluded from this limit to maintain readability.
9+
10+
### Table Line Length Configuration
11+
12+
Tables are configured to ignore line length limits globally via the `.markdownlint.json` configuration:
13+
14+
```json
15+
"MD013": {
16+
"line_length": 100,
17+
"tables": false
18+
}
19+
```
20+
21+
This means:
22+
23+
- **Regular text**: Must stay within 100 characters per line
24+
- **Tables**: Can exceed line length limits without linting errors
25+
- **Code blocks**: Follow normal line length rules
26+
27+
### Alternative Approach
28+
29+
If you need to disable line length for specific non-table content, you can still use
30+
markdownlint ignore blocks:
31+
32+
```markdown
33+
<!-- markdownlint-disable MD013 -->
34+
35+
Very long line content that needs to exceed the normal limit
36+
37+
<!-- markdownlint-enable MD013 -->
38+
```

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Torrust
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Torrust Tracker Deployment Tool
2+
3+
A modern Perl console application for deploying Torrust Tracker to Hetzner Cloud using Packer,
4+
Terraform, and Ansible.
5+
6+
## Installation
7+
8+
Install cpanminus:
9+
10+
```bash
11+
curl -L https://cpanmin.us | perl - --sudo App::cpanminus
12+
```
13+
14+
Install local::lib:
15+
16+
```bash
17+
cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
18+
```
19+
20+
Install Carmel dependency manager:
21+
22+
```bash
23+
cpanm Carmel
24+
```
25+
26+
Set up the environment (add carmel to PATH and set PERL5LIB):
27+
28+
```bash
29+
eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
30+
export PATH="$HOME/perl5/bin:$PATH"
31+
```
32+
33+
**Note:** You need to run the `eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)` command in each new
34+
terminal session, or add it to your shell profile (`.bashrc`, `.zshrc`, etc.).
35+
36+
Then install project dependencies:
37+
38+
```bash
39+
carmel install
40+
```
41+
42+
## Usage
43+
44+
Run the application:
45+
46+
```bash
47+
carmel exec -- ./bin/torrust-deploy help
48+
```
49+
50+
## Testing
51+
52+
Run the test suite:
53+
54+
```bash
55+
carmel exec -- prove -l t/
56+
```

bin/torrust-deploy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env perl # Shebang line - tells the system to use perl to execute this script
2+
3+
# Set up Perl environment with safety features
4+
use strict; # Enable strict mode - catches common programming errors like undeclared variables
5+
use warnings; # Enable warnings - shows potential issues in the code
6+
use v5.20; # Require Perl version 5.20 or higher for modern language features
7+
8+
# Configure module loading
9+
use FindBin qw($Bin); # Import FindBin module and get $Bin variable containing this script's directory
10+
use lib "$Bin/../lib"; # Add the lib directory (relative to this script) to Perl's module search path
11+
12+
# Load and execute application
13+
use TorrustDeploy::App; # Load our main application module
14+
TorrustDeploy::App->run; # Execute the application with command-line arguments from @ARGV

cpanfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
requires 'perl', '5.020';
2+
requires 'App::Cmd';
3+
requires 'Moo';
4+
requires 'namespace::clean';
5+
requires 'Path::Tiny';
6+
7+
on 'test' => sub {
8+
requires 'Test2::Suite';
9+
requires 'Test::MockModule';
10+
};
11+
12+
on 'develop' => sub {
13+
requires 'Perl::Critic';
14+
requires 'Perl::Tidy';
15+
};

cspell.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
3+
"version": "0.2",
4+
"dictionaryDefinitions": [
5+
{
6+
"name": "project-words",
7+
"path": "./project-words.txt",
8+
"addWords": true
9+
}
10+
],
11+
"dictionaries": [
12+
"project-words"
13+
],
14+
"ignorePaths": [
15+
"target",
16+
"/project-words.txt"
17+
]
18+
}

0 commit comments

Comments
 (0)