or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdapi-client.mdapps.mdexceptions.mdhttp-implementations.mdindex.mdrouting.mdsansio.md

actions.mddocs/

0

# GitHub Actions

1

2

Utilities for GitHub Actions workflows including environment variable management, path manipulation, and logging command output. These functions help create GitHub Actions that integrate with the workflow environment.

3

4

## Capabilities

5

6

### Workspace Access

7

8

Access the GitHub Actions workspace directory.

9

10

```python { .api }

11

import pathlib

12

13

def workspace() -> pathlib.Path:

14

"""

15

Return the action workspace as a pathlib.Path object.

16

17

Returns:

18

- Path object pointing to the workspace directory

19

20

Note: Uses the GITHUB_WORKSPACE environment variable.

21

This function is cached with @functools.lru_cache(maxsize=1).

22

"""

23

```

24

25

### Event Data Access

26

27

Access the webhook event that triggered the workflow.

28

29

```python { .api }

30

def event() -> Any:

31

"""

32

Return the webhook event data for the running action.

33

34

Returns:

35

- Parsed JSON data from the event that triggered the workflow

36

37

Note: Uses the GITHUB_EVENT_PATH environment variable.

38

This function is cached with @functools.lru_cache(maxsize=1).

39

"""

40

```

41

42

### Workflow Commands

43

44

Issue logging commands that are processed by the GitHub Actions runner.

45

46

```python { .api }

47

def command(cmd: str, data: str = "", **parameters: str) -> None:

48

"""

49

Issue a logging command that will be processed by the Actions runner.

50

51

Parameters:

52

- cmd: Command name (e.g., "error", "warning", "notice", "debug")

53

- data: Command data/message

54

- **parameters: Command parameters (e.g., file, line, col, title)

55

56

Examples:

57

- command("error", "Something went wrong", file="app.py", line="42")

58

- command("warning", "Deprecated function used")

59

- command("notice", "Build completed successfully")

60

"""

61

```

62

63

### Environment Management

64

65

Manage environment variables for the current and future actions.

66

67

```python { .api }

68

def setenv(name: str, value: str) -> None:

69

"""

70

Create or update an environment variable.

71

The change applies to this action and future actions in the job.

72

73

Parameters:

74

- name: Environment variable name

75

- value: Environment variable value (can be multiline)

76

77

Note: Uses the GITHUB_ENV environment file for persistence.

78

"""

79

80

def addpath(path: Union[str, "os.PathLike[str]"]) -> None:

81

"""

82

Prepend a directory to the PATH environment variable.

83

This affects this action and all subsequent actions in the current job.

84

85

Parameters:

86

- path: Directory path to add to PATH

87

88

Note: Uses the GITHUB_PATH environment file for persistence.

89

"""

90

```

91

92

## Usage Examples

93

94

### Basic Action Script

95

96

```python

97

#!/usr/bin/env python3

98

import gidgethub.actions

99

import subprocess

100

import sys

101

102

def main():

103

# Get workspace directory

104

workspace = gidgethub.actions.workspace()

105

print(f"Working in: {workspace}")

106

107

# Get event data

108

event_data = gidgethub.actions.event()

109

event_name = event_data.get('action', 'unknown')

110

111

gidgethub.actions.command("notice", f"Processing {event_name} event")

112

113

# Example: Run tests

114

try:

115

result = subprocess.run(

116

["python", "-m", "pytest"],

117

cwd=workspace,

118

capture_output=True,

119

text=True

120

)

121

122

if result.returncode == 0:

123

gidgethub.actions.command("notice", "Tests passed successfully")

124

else:

125

gidgethub.actions.command("error", f"Tests failed: {result.stderr}")

126

sys.exit(1)

127

128

except Exception as e:

129

gidgethub.actions.command("error", f"Failed to run tests: {e}")

130

sys.exit(1)

131

132

if __name__ == "__main__":

133

main()

134

```

135

136

### Environment Variable Management

137

138

```python

139

import gidgethub.actions

140

import os

141

142

def setup_build_environment():

143

# Set build configuration

144

gidgethub.actions.setenv("BUILD_TYPE", "release")

145

gidgethub.actions.setenv("OPTIMIZATION_LEVEL", "3")

146

147

# Set multiline environment variable

148

config_json = """{

149

"api_url": "https://api.example.com",

150

"timeout": 30,

151

"retries": 3

152

}"""

153

gidgethub.actions.setenv("BUILD_CONFIG", config_json)

154

155

# Add custom tools to PATH

156

tools_dir = gidgethub.actions.workspace() / "tools" / "bin"

157

gidgethub.actions.addpath(tools_dir)

158

159

# Verify environment

160

print(f"BUILD_TYPE: {os.environ.get('BUILD_TYPE')}")

161

print(f"PATH includes tools: {str(tools_dir) in os.environ.get('PATH', '')}")

162

163

setup_build_environment()

164

```

165

166

### Error Reporting with File Locations

167

168

```python

169

import gidgethub.actions

170

import ast

171

import sys

172

173

def lint_python_file(file_path):

174

"""Lint a Python file and report errors with locations."""

175

try:

176

with open(file_path, 'r') as f:

177

source = f.read()

178

179

# Parse the file

180

ast.parse(source)

181

gidgethub.actions.command("notice", f"βœ“ {file_path} is valid Python")

182

183

except SyntaxError as e:

184

# Report syntax error with file location

185

gidgethub.actions.command(

186

"error",

187

f"Syntax error: {e.msg}",

188

file=str(file_path),

189

line=str(e.lineno),

190

col=str(e.offset) if e.offset else "1"

191

)

192

return False

193

194

except Exception as e:

195

gidgethub.actions.command("error", f"Failed to process {file_path}: {e}")

196

return False

197

198

return True

199

200

def main():

201

workspace = gidgethub.actions.workspace()

202

python_files = list(workspace.glob("**/*.py"))

203

204

gidgethub.actions.command("notice", f"Linting {len(python_files)} Python files")

205

206

all_valid = True

207

for py_file in python_files:

208

if not lint_python_file(py_file):

209

all_valid = False

210

211

if not all_valid:

212

gidgethub.actions.command("error", "Linting failed")

213

sys.exit(1)

214

else:

215

gidgethub.actions.command("notice", "All files passed linting")

216

217

if __name__ == "__main__":

218

main()

219

```

220

221

### Processing Webhook Events

222

223

```python

224

import gidgethub.actions

225

226

def process_pull_request_event():

227

event = gidgethub.actions.event()

228

229

if event.get('action') == 'opened':

230

pr = event['pull_request']

231

232

gidgethub.actions.command(

233

"notice",

234

f"New PR opened: {pr['title']}",

235

title="Pull Request Opened"

236

)

237

238

# Check if PR affects specific files

239

changed_files = [] # You'd get this from the GitHub API

240

if any(f.endswith('.py') for f in changed_files):

241

gidgethub.actions.setenv("RUN_PYTHON_TESTS", "true")

242

243

if any(f.endswith(('.js', '.ts')) for f in changed_files):

244

gidgethub.actions.setenv("RUN_JS_TESTS", "true")

245

246

elif event.get('action') == 'closed':

247

pr = event['pull_request']

248

if pr['merged']:

249

gidgethub.actions.command("notice", f"PR merged: {pr['title']}")

250

else:

251

gidgethub.actions.command("notice", f"PR closed: {pr['title']}")

252

253

process_pull_request_event()

254

```

255

256

### Custom Action with Inputs and Outputs

257

258

```python

259

import gidgethub.actions

260

import os

261

import json

262

263

def parse_inputs():

264

"""Parse action inputs from environment variables."""

265

return {

266

'target': os.environ.get('INPUT_TARGET', 'main'),

267

'dry_run': os.environ.get('INPUT_DRY_RUN', 'false').lower() == 'true',

268

'config_file': os.environ.get('INPUT_CONFIG_FILE', 'config.json')

269

}

270

271

def set_outputs(**outputs):

272

"""Set action outputs."""

273

for key, value in outputs.items():

274

# GitHub Actions uses special echo commands for outputs

275

print(f"::set-output name={key}::{value}")

276

277

def main():

278

inputs = parse_inputs()

279

280

gidgethub.actions.command(

281

"notice",

282

f"Running with target: {inputs['target']}, dry_run: {inputs['dry_run']}"

283

)

284

285

workspace = gidgethub.actions.workspace()

286

config_path = workspace / inputs['config_file']

287

288

if not config_path.exists():

289

gidgethub.actions.command(

290

"error",

291

f"Config file not found: {config_path}",

292

file=str(config_path)

293

)

294

return 1

295

296

# Process configuration

297

try:

298

with open(config_path) as f:

299

config = json.load(f)

300

301

# Set outputs for other actions to use

302

set_outputs(

303

config_valid="true",

304

target_branch=inputs['target'],

305

config_version=config.get('version', 'unknown')

306

)

307

308

gidgethub.actions.command("notice", "Action completed successfully")

309

return 0

310

311

except Exception as e:

312

gidgethub.actions.command("error", f"Failed to process config: {e}")

313

return 1

314

315

if __name__ == "__main__":

316

exit_code = main()

317

exit(exit_code)

318

```

319

320

### Integration with gidgethub API Client

321

322

```python

323

import asyncio

324

import aiohttp

325

import gidgethub.actions

326

from gidgethub.aiohttp import GitHubAPI

327

328

async def comment_on_pr():

329

"""Add a comment to the PR that triggered this action."""

330

event = gidgethub.actions.event()

331

332

if event.get('action') != 'opened':

333

gidgethub.actions.command("notice", "Not a PR opened event, skipping")

334

return

335

336

# Get GitHub token from environment

337

github_token = os.environ.get('GITHUB_TOKEN')

338

if not github_token:

339

gidgethub.actions.command("error", "GITHUB_TOKEN not set")

340

return

341

342

repository = event['repository']['full_name']

343

pr_number = event['pull_request']['number']

344

345

async with aiohttp.ClientSession() as session:

346

gh = GitHubAPI(session, "pr-commenter/1.0", oauth_token=github_token)

347

348

try:

349

# Add comment to PR

350

await gh.post(

351

f"/repos/{repository}/issues/{pr_number}/comments",

352

data={

353

"body": "πŸŽ‰ Thanks for opening this PR! Our automated checks are running."

354

}

355

)

356

357

gidgethub.actions.command("notice", f"Added comment to PR #{pr_number}")

358

359

except Exception as e:

360

gidgethub.actions.command("error", f"Failed to add comment: {e}")

361

362

# Run the async function

363

asyncio.run(comment_on_pr())

364

```

365

366

## GitHub Actions Environment Variables

367

368

Common environment variables available in GitHub Actions:

369

370

- `GITHUB_WORKSPACE`: The workspace directory path

371

- `GITHUB_EVENT_PATH`: Path to the webhook event JSON file

372

- `GITHUB_TOKEN`: GitHub token for API access

373

- `GITHUB_REPOSITORY`: Repository name (owner/name)

374

- `GITHUB_REF`: Git ref that triggered the workflow

375

- `GITHUB_SHA`: Commit SHA that triggered the workflow

376

- `GITHUB_ACTOR`: Username of the user that triggered the workflow

377

- `GITHUB_WORKFLOW`: Name of the workflow

378

- `GITHUB_RUN_ID`: Unique identifier for the workflow run

379

- `GITHUB_RUN_NUMBER`: Sequential number for the workflow run

380

381

## Workflow Command Reference

382

383

Common workflow commands you can use with the `command()` function:

384

385

- `error`: Create an error message

386

- `warning`: Create a warning message

387

- `notice`: Create a notice message

388

- `debug`: Create a debug message

389

- `group`: Start a collapsible group

390

- `endgroup`: End a collapsible group

391

- `save-state`: Save state for post-action

392

- `set-output`: Set action output (deprecated, use environment files)

393

394

## Types

395

396

```python { .api }

397

import pathlib

398

import os

399

from typing import Any, Union

400

401

# Path types for workspace and file operations

402

PathLike = Union[str, "os.PathLike[str]"]

403

WorkspacePath = pathlib.Path

404

405

# Event data type (parsed JSON)

406

EventData = Any # Dictionary containing webhook event data

407

```