feat: embed build metadata in generated dotslash files (#13)
* feat: embed build metadata in generated dotslash files - Add build metadata collection from GitHub Actions environment - Include source config path, CI information, and generation timestamp - Add CI job URL for traceability back to the generating workflow - Support disabling metadata via include-build-metadata input - Update action.yml to expose new input parameter - Add comprehensive documentation with examples Fixes #2 * feat: pass include-build-metadata as argument instead of environment variable - Remove environment variable approach from action.yml - Pass include-build-metadata as command-line argument - Update argument parsing to handle string values ('true'/'false') - Maintain backward compatibility with environment variable fallback Addresses review feedback from @bigfootjon in PR #13
This commit is contained in:
@@ -261,6 +261,56 @@ Each platform entry recognizes the following properties:
|
||||
* `hash` must be one of `"blake3"` or `"sha256"`, but it defaults to `"blake3"`,
|
||||
so it is optional.
|
||||
|
||||
## Action Inputs
|
||||
|
||||
This action supports the following inputs:
|
||||
|
||||
* `config` (required): Path to .json file in the repo that defines how DotSlash files should be generated.
|
||||
* `tag` (required): Tag identifying the release whose assets should be used.
|
||||
* `include-build-metadata` (optional): Whether to include build metadata in the generated DotSlash files. Defaults to `true`.
|
||||
|
||||
## Build Metadata
|
||||
|
||||
By default, the action embeds build metadata in the generated DotSlash files to provide traceability about how and when the files were generated. This metadata includes:
|
||||
|
||||
* **Source configuration**: Path to the config file used to generate the DotSlash file
|
||||
* **CI information**: Repository, commit SHA, run ID, workflow name, actor, and event type
|
||||
* **Generation timestamp**: When the DotSlash file was generated
|
||||
* **CI job URL**: Direct link to the GitHub Actions run that generated the file
|
||||
|
||||
Example of embedded metadata:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-tool",
|
||||
"platforms": { ... },
|
||||
"build_metadata": {
|
||||
"source_config": ".github/workflows/dotslash-config.json",
|
||||
"ci": {
|
||||
"github_repository": "owner/repo",
|
||||
"github_sha": "abc123def456",
|
||||
"github_run_id": "987654321",
|
||||
"github_workflow": "Build and Release",
|
||||
"github_actor": "john-doe",
|
||||
"github_event_name": "release",
|
||||
"github_server_url": "https://github.com"
|
||||
},
|
||||
"generated_at": "2025-09-28T15:23:57.878282Z",
|
||||
"ci_job_url": "https://github.com/owner/repo/actions/runs/987654321"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To disable build metadata inclusion, set `include-build-metadata` to `false`:
|
||||
|
||||
```yaml
|
||||
- uses: facebook/dotslash-publish-release@v1
|
||||
with:
|
||||
config: .github/workflows/dotslash-config.json
|
||||
tag: ${{ github.event.workflow_run.head_branch }}
|
||||
include-build-metadata: false
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
dotslash-publish-release is [MIT licensed](./LICENSE).
|
||||
|
||||
@@ -7,6 +7,10 @@ inputs:
|
||||
tag:
|
||||
description: tag identifying the release whose assets should be used
|
||||
required: true
|
||||
include-build-metadata:
|
||||
description: include build metadata in the generated DotSlash files
|
||||
required: false
|
||||
default: 'true'
|
||||
runs:
|
||||
using: docker
|
||||
image: Dockerfile
|
||||
@@ -16,3 +20,5 @@ runs:
|
||||
- '--tag'
|
||||
- ${{ inputs.tag }}
|
||||
- '--upload'
|
||||
- '--include-build-metadata'
|
||||
- ${{ inputs.include-build-metadata }}
|
||||
|
||||
@@ -12,6 +12,7 @@ import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import datetime
|
||||
|
||||
from functools import cache
|
||||
from typing import Any, Dict, Literal, Optional, Tuple, Union
|
||||
@@ -26,6 +27,47 @@ EXCLUDE_HTTP_PROVIDER_PARAM = "exclude-http-provider"
|
||||
EXCLUDE_GITHUB_PROVIDER_PARAM = "exclude-github-release-provider"
|
||||
|
||||
|
||||
def collect_build_metadata(config_path: str) -> Dict[str, Any]:
|
||||
"""Collect build metadata from GitHub Actions environment variables."""
|
||||
metadata = {}
|
||||
|
||||
# Source file information
|
||||
if config_path:
|
||||
metadata["source_config"] = config_path
|
||||
|
||||
# CI/GitHub Actions information
|
||||
github_env_vars = [
|
||||
("github_repository", "GITHUB_REPOSITORY"),
|
||||
("github_ref", "GITHUB_REF"),
|
||||
("github_sha", "GITHUB_SHA"),
|
||||
("github_run_id", "GITHUB_RUN_ID"),
|
||||
("github_run_number", "GITHUB_RUN_NUMBER"),
|
||||
("github_workflow", "GITHUB_WORKFLOW"),
|
||||
("github_actor", "GITHUB_ACTOR"),
|
||||
("github_event_name", "GITHUB_EVENT_NAME"),
|
||||
("github_server_url", "GITHUB_SERVER_URL"),
|
||||
]
|
||||
|
||||
ci_info = {}
|
||||
for key, env_var in github_env_vars:
|
||||
value = os.getenv(env_var)
|
||||
if value:
|
||||
ci_info[key] = value
|
||||
|
||||
if ci_info:
|
||||
metadata["ci"] = ci_info
|
||||
|
||||
# Build timestamp
|
||||
metadata["generated_at"] = datetime.datetime.utcnow().isoformat() + "Z"
|
||||
|
||||
# Add link to the CI job if we have the necessary info
|
||||
if all(os.getenv(var) for var in ["GITHUB_SERVER_URL", "GITHUB_REPOSITORY", "GITHUB_RUN_ID"]):
|
||||
job_url = f"{os.getenv('GITHUB_SERVER_URL')}/{os.getenv('GITHUB_REPOSITORY')}/actions/runs/{os.getenv('GITHUB_RUN_ID')}"
|
||||
metadata["ci_job_url"] = job_url
|
||||
|
||||
return metadata
|
||||
|
||||
|
||||
def main() -> None:
|
||||
exit_code = _main()
|
||||
sys.exit(exit_code)
|
||||
@@ -93,6 +135,23 @@ def _main() -> int:
|
||||
logging.info("using config:")
|
||||
logging.info(json.dumps(config, indent=2))
|
||||
|
||||
# Collect build metadata from the environment
|
||||
build_metadata = None
|
||||
|
||||
# Convert string argument to boolean
|
||||
include_metadata_str = str(args.include_build_metadata).lower()
|
||||
include_metadata = include_metadata_str not in ["false", "0", "no"] and not args.exclude_build_metadata
|
||||
|
||||
# Also check for environment variable (for Docker action support)
|
||||
include_metadata_env = os.getenv("INCLUDE_BUILD_METADATA", "true").lower()
|
||||
if include_metadata_env in ["false", "0", "no"]:
|
||||
include_metadata = False
|
||||
|
||||
if include_metadata:
|
||||
build_metadata = collect_build_metadata(args.config)
|
||||
logging.info("build metadata:")
|
||||
logging.info(json.dumps(build_metadata, indent=2))
|
||||
|
||||
name_to_asset = get_release_assets(tag=tag, github_repository=repo)
|
||||
logging.info(json.dumps(name_to_asset, indent=2))
|
||||
|
||||
@@ -111,6 +170,7 @@ def _main() -> int:
|
||||
platform_entries,
|
||||
include_http_provider=not exclude_http_provider,
|
||||
include_github_release_provider=not exclude_github_release_provider,
|
||||
build_metadata=build_metadata,
|
||||
)
|
||||
logging.info(manifest_file_contents)
|
||||
|
||||
@@ -150,6 +210,7 @@ def generate_manifest_file(
|
||||
platform_entries,
|
||||
include_http_provider: bool,
|
||||
include_github_release_provider: bool,
|
||||
build_metadata: Optional[Dict[str, Any]] = None,
|
||||
) -> str:
|
||||
platforms = {}
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
@@ -224,6 +285,10 @@ def generate_manifest_file(
|
||||
"name": name,
|
||||
"platforms": platforms,
|
||||
}
|
||||
|
||||
# Add build metadata if available
|
||||
if build_metadata:
|
||||
manifest["build_metadata"] = build_metadata
|
||||
|
||||
return f"""#!/usr/bin/env dotslash
|
||||
|
||||
@@ -458,6 +523,19 @@ def parse_args():
|
||||
default=os.getenv("GITHUB_WORKSPACE"),
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--include-build-metadata",
|
||||
type=str,
|
||||
default="true",
|
||||
help="include build metadata in the generated DotSlash files (default: true)",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--exclude-build-metadata",
|
||||
action="store_true",
|
||||
help="exclude build metadata from the generated DotSlash files",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user