Skip to content

Commit

Permalink
feat: process env files
Browse files Browse the repository at this point in the history
  • Loading branch information
roderik committed Dec 14, 2024
1 parent d8a3ff4 commit e6fcc3f
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 6 deletions.
7 changes: 4 additions & 3 deletions .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
8. Support all SettleMint environment variables as optional inputs
9. Set predefined contract addresses as environment variables
10. Add auto-login and auto-connect functionality
11. Add comprehensive test coverage for main functionality
12. Configure Renovate to run `npm run package` after dependency updates
13. Create comprehensive README documentation with examples and best practices
11. Process .env files from secrets and add them to GitHub environment
12. Add comprehensive test coverage for main functionality
13. Configure Renovate to run `npm run package` after dependency updates
14. Create comprehensive README documentation with examples and best practices
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,29 @@ All inputs are automatically converted to environment variables with the `SETTLE
- `workspace` → `SETTLEMINT_WORKSPACE`
- `blockchain-network` → `SETTLEMINT_BLOCKCHAIN_NETWORK`

### Environment Files
The action supports loading environment variables from `.env` files. You can provide the content of your env files through the following inputs:

- `dotEnvFile`: Content of your main `.env` file
- `dotEnvLocalFile`: Content of your `.env.local` file

⚠️ **Important**: Always store env file contents in GitHub Secrets:
```yaml
steps:
- uses: settlemint/settlemint-action@main
with:
dotEnvFile: ${{ secrets.MY_ENV_FILE }}
dotEnvLocalFile: ${{ secrets.MY_ENV_LOCAL }}
access-token: ${{ secrets.SETTLEMINT_ACCESS_TOKEN }}
```

The action will process these files and add all variables to the GitHub Actions environment. It handles:
- Comments (lines starting with #)
- Empty lines
- Quoted values
- Values containing = signs
- Trailing comments

## Error Handling

The action will fail if:
Expand All @@ -153,6 +176,32 @@ The action will fail if:
- Use GitHub Secrets for sensitive information
- Consider using OIDC for token management in production

## Security Best Practices

### Handling Secrets 🔒
- **NEVER** commit access tokens, private keys or any secrets directly in your workflow files or repository
- **ALWAYS** use GitHub Secrets for sensitive information:
```yaml
# ✅ CORRECT - Using GitHub Secrets
access-token: ${{ secrets.SETTLEMINT_ACCESS_TOKEN }}
# ❌ WRONG - NEVER do this
access-token: "your-token-here" # This is a security risk!
```
- Use GitHub's OIDC (OpenID Connect) for token management in production environments
- Regularly rotate your access tokens and secrets
- Limit secret access to only the necessary workflows and repositories

### Environment Variables
When using .env files:
```yaml
steps:
- uses: settlemint/settlemint-action@main
with:
dotEnvFile: ${{ secrets.ENV_FILE_CONTENT }} # Store as a secret!
access-token: ${{ secrets.SETTLEMINT_ACCESS_TOKEN }}
```

## Contributing

Contributions are welcome! Please read our [Contributing Guide](./.github/CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ inputs:
smart-contract-set:
description: 'SettleMint smart contract set ID'
required: false
dotEnvFile:
description: 'A Github Actions secret containing the .env file, loaded in one go for easy updates'
required: false
dotEnvLocalFile:
description: 'A Github Actions secret containing the .env.local file, loaded in one go for easy updates'
required: false

runs:
using: node20
Expand Down
2 changes: 1 addition & 1 deletion badges/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "typescript-action",
"description": "GitHub Actions TypeScript template",
"version": "0.6.0",
"version": "0.6.1",
"author": "",
"private": true,
"homepage": "https://github.com/actions/typescript-action",
Expand Down
42 changes: 42 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,37 @@ const ENV_VARS = [
'smart-contract-set',
];

const ENV_VAR_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*=/;
const QUOTE_PATTERN = /^["'](.*)["']$/;

function processEnvContent(content: string): void {
const lines = content.split('\n');

for (const line of lines) {
const trimmedLine = line.trim();

// Skip empty lines and comments
if (!trimmedLine || trimmedLine.startsWith('#')) {
continue;
}

// Remove trailing comments and trim
const lineWithoutComments = trimmedLine.split('#')[0].trim();

// Check if line matches env var pattern
if (ENV_VAR_PATTERN.test(lineWithoutComments)) {
const [key, ...valueParts] = lineWithoutComments.split('=');
let value = valueParts.join('='); // Rejoin in case value contains =

// Remove surrounding quotes if they exist
value = value.replace(QUOTE_PATTERN, '$1');

// Set in GitHub environment
core.exportVariable(key.trim(), value.trim());
}
}
}

/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
Expand All @@ -36,6 +67,17 @@ export async function run(): Promise<void> {
core.debug('Installing SettleMint CLI...');
await exec.exec('npm', ['install', '-g', `@settlemint/sdk-cli@${version}`]);

// Process .env files
const dotEnvFile = core.getInput('dotEnvFile');
if (dotEnvFile) {
processEnvContent(dotEnvFile);
}

const dotEnvLocalFile = core.getInput('dotEnvLocalFile');
if (dotEnvLocalFile) {
processEnvContent(dotEnvLocalFile);
}

// Set optional environment variables
for (const varName of ENV_VARS) {
const value = core.getInput(varName);
Expand Down

0 comments on commit e6fcc3f

Please sign in to comment.