1/*
2 * Copyright 2019 GitHub
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22
23import {issue, issueCommand} from './command'
24
25import * as os from 'os'
26import * as path from 'path'
27
28/**
29 * Interface for getInput options
30 */
31export interface InputOptions {
32 /** Optional. Whether the input is required. If required and not present, will throw. Defaults to false */
33 required?: boolean
34}
35
36/**
37 * The code to exit an action
38 */
39export enum ExitCode {
40 /**
41 * A code indicating that the action was successful
42 */
43 Success = 0,
44
45 /**
46 * A code indicating that the action was a failure
47 */
48 Failure = 1
49}
50
51//-----------------------------------------------------------------------
52// Variables
53//-----------------------------------------------------------------------
54
55/**
56 * Sets env variable for this action and future actions in the job
57 * @param name the name of the variable to set
58 * @param val the value of the variable
59 */
60export function exportVariable(name: string, val: string): void {
61 process.env[name] = val
62 issueCommand('set-env', {name}, val)
63}
64
65/**
66 * Registers a secret which will get masked from logs
67 * @param secret value of the secret
68 */
69export function setSecret(secret: string): void {
70 issueCommand('add-mask', {}, secret)
71}
72
73/**
74 * Prepends inputPath to the PATH (for this action and future actions)
75 * @param inputPath
76 */
77export function addPath(inputPath: string): void {
78 issueCommand('add-path', {}, inputPath)
79 process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`
80}
81
82/**
83 * Gets the value of an input. The value is also trimmed.
84 *
85 * @param name name of the input to get
86 * @param options optional. See InputOptions.
87 * @returns string
88 */
89export function getInput(name: string, options?: InputOptions): string {
90 const val: string =
91 process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''
92 if (options && options.required && !val) {
93 throw new Error(`Input required and not supplied: ${name}`)
94 }
95
96 return val.trim()
97}
98
99/**
100 * Sets the value of an output.
101 *
102 * @param name name of the output to set
103 * @param value value to store
104 */
105export function setOutput(name: string, value: string): void {
106 issueCommand('set-output', {name}, value)
107}
108
109//-----------------------------------------------------------------------
110// Results
111//-----------------------------------------------------------------------
112
113/**
114 * Sets the action status to failed.
115 * When the action exits it will be with an exit code of 1
116 * @param message add error issue message
117 */
118export function setFailed(message: string): void {
119 process.exitCode = ExitCode.Failure
120 error(message)
121}
122
123//-----------------------------------------------------------------------
124// Logging Commands
125//-----------------------------------------------------------------------
126
127/**
128 * Writes debug message to user log
129 * @param message debug message
130 */
131export function debug(message: string): void {
132 issueCommand('debug', {}, message)
133}
134
135/**
136 * Adds an error issue
137 * @param message error issue message
138 */
139export function error(message: string): void {
140 issue('error', message)
141}
142
143/**
144 * Adds an warning issue
145 * @param message warning issue message
146 */
147export function warning(message: string): void {
148 issue('warning', message)
149}
150
151/**
152 * Writes info to log with console.log.
153 * @param message info message
154 */
155export function info(message: string): void {
156 process.stdout.write(message + os.EOL)
157}
158
159/**
160 * Begin an output group.
161 *
162 * Output until the next `groupEnd` will be foldable in this group
163 *
164 * @param name The name of the output group
165 */
166export function startGroup(name: string): void {
167 issue('group', name)
168}
169
170/**
171 * End an output group.
172 */
173export function endGroup(): void {
174 issue('endgroup')
175}
176
177/**
178 * Wrap an asynchronous function call in a group.
179 *
180 * Returns the same type as the function itself.
181 *
182 * @param name The name of the group
183 * @param fn The function to wrap in the group
184 */
185export async function group<T>(name: string, fn: () => Promise<T>): Promise<T> {
186 startGroup(name)
187
188 let result: T
189
190 try {
191 result = await fn()
192 } finally {
193 endGroup()
194 }
195
196 return result
197}
198
199//-----------------------------------------------------------------------
200// Wrapper action state
201//-----------------------------------------------------------------------
202
203/**
204 * Saves state for current action, the state can only be retrieved by this action's post job execution.
205 *
206 * @param name name of the state to store
207 * @param value value to store
208 */
209export function saveState(name: string, value: string): void {
210 issueCommand('save-state', {name}, value)
211}
212
213/**
214 * Gets the value of an state set by this action's main execution.
215 *
216 * @param name name of the state to get
217 * @returns string
218 */
219export function getState(name: string): string {
220 return process.env[`STATE_${name}`] || ''
221}
222
223export function foo(): any {
224 // The following is not valid syntax.
225 return [100n, 1_000, 0777, unique symbol]
226}
227