Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
SdmGoal,
SdmGoalKey,
} from "../../../../ingesters/sdmGoalIngester";
import { fetchGoalsForCommit } from "../../../../internal/delivery/goals/support/fetchGoalsOnCommit";
import { isGoalRelevant } from "../../../../internal/delivery/goals/support/validateGoal";
import { RepoRefResolver } from "../../../../spi/repo-ref/RepoRefResolver";
import {
OnAnySuccessfulSdmGoal,
ScmProvider,
} from "../../../../typings/types";
/**
* Respond to a failure status by failing downstream goals
*/
@EventHandler("Move downstream goals from 'planned' to 'success' when preconditions are met",
subscription("OnAnySuccessfulSdmGoal"))
export class RequestDownstreamGoalsOnGoalSuccess implements HandleEvent {
@Value("token")
public githubToken: string;
constructor(private readonly implementationMapper: SdmGoalImplementationMapper,
private readonly repoRefResolver: RepoRefResolver) { }
// #98: GitHub Status->SdmGoal: I believe all the goal state updates in this SDM
// are now happening on the SdmGoal. This subscription can change to be on SdmGoal state.
public async handle(event: EventFired,
context: HandlerContext,
params: this): Promise {
const sdmGoal = event.data.SdmGoal[0] as SdmGoal;
if (!isGoalRelevant(sdmGoal)) {
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventFired, EventHandler, HandleEvent, HandlerContext, HandlerResult, logger, Success } from "@atomist/automation-client";
import { subscription } from "@atomist/automation-client/graph/graphQL";
import { GitHubRepoRef } from "@atomist/automation-client/operations/common/GitHubRepoRef";
import { forApproval } from "../../../handlers/events/delivery/verify/approvalGate";
import * as GoalEvent from "../../../ingesters/sdmGoalIngester";
import { SdmGoalState } from "../../../ingesters/sdmGoalIngester";
import { OnAnyGoal, StatusState } from "../../../typings/types";
import { createStatus } from "../../../util/github/ghub";
import { fetchProvider } from "../../../util/github/gitHubProvider";
@EventHandler("Copy every SdmGoal to a GitHub Status", subscription({name: "OnAnyGoal"}))
export class CopyGoalToGitHubStatus implements HandleEvent {
// TODO: @cd why doesn't this work, it doesn't register for the secret
// @Secret(Secrets.OrgToken)
// private readonly githubToken: string = process.env.GITHUB_TOKEN;
public async handle(event: EventFired, context: HandlerContext, params: this): Promise {
const goal = event.data.SdmGoal[0];
if (!goal.externalKey) {
logger.debug("No external key on goal %s. Skipping", goal.name);
return Success;
}
// Too many updates close together get mixed up.
// For now, skip in_process updates. Someday we may change this,
// when it's SdmGoals that are displayed in lifecycle and only some
* limitations under the License.
*/
import { EventFired, EventHandler, HandleEvent, HandlerContext, HandlerResult, logger, Success } from "@atomist/automation-client";
import { subscription } from "@atomist/automation-client/graph/graphQL";
import { updateGoal } from "../../../../common/delivery/goals/storeGoals";
import { fetchGoalsForCommit } from "../../../../common/delivery/goals/support/fetchGoalsOnCommit";
import { SdmGoal } from "../../../../ingesters/sdmGoalIngester";
import { OnAnySuccessStatus } from "../../../../typings/types";
import { providerIdFromStatus, repoRefFromStatus } from "../../../../util/git/repoRef";
/**
* #98: this is temporary, until Lifecycle-automation is changed to mark goals approved
*/
@EventHandler("When Lifecycle marks a status approved, copy that to the goal",
subscription("OnAnySuccessStatus"))
export class CopyStatusApprovalToGoal implements HandleEvent {
public async handle(event: EventFired,
ctx: HandlerContext): Promise {
const status = event.data.Status[0];
if (!status.description.includes("approved by ")) {
logger.debug("not an approval: " + status.description);
return Success;
}
const sdmGoal = (await fetchGoalsForCommit(ctx, repoRefFromStatus(status), providerIdFromStatus(status)))
.find(sg => sg.externalKey === status.context) as SdmGoal;
if (!sdmGoal) {
logger.warn("Goal not found for approval status: %j", status);
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventFired, EventHandler, HandleEvent, HandlerContext, HandlerResult, Success } from "@atomist/automation-client";
import { subscription } from "@atomist/automation-client/graph/graphQL";
import { AddressNoChannels } from "../../../api/context/addressChannels";
import { RepoCreationListener, RepoCreationListenerInvocation } from "../../../api/listener/RepoCreationListener";
import { CredentialsResolver } from "../../../spi/credentials/CredentialsResolver";
import { RepoRefResolver } from "../../../spi/repo-ref/RepoRefResolver";
import * as schema from "../../../typings/types";
/**
* A new repo has been created. We don't know if it has code.
*/
@EventHandler("On repo creation", subscription("OnRepoCreation"))
export class OnRepoCreation implements HandleEvent {
private readonly newRepoActions: RepoCreationListener[];
constructor(newRepoActions: RepoCreationListener[],
private readonly repoRefResolver: RepoRefResolver,
private readonly credentialsFactory: CredentialsResolver) {
this.newRepoActions = newRepoActions;
}
public async handle(event: EventFired,
context: HandlerContext,
params: this): Promise {
const repo = event.data.Repo[0];
const id = params.repoRefResolver.toRemoteRepoRef(repo, {});
const credentials = this.credentialsFactory.eventHandlerCredentials(context, id);
logger,
Success,
Value,
} from "@atomist/automation-client";
import { subscription } from "@atomist/automation-client/graph/graphQL";
import { addressChannelsFor } from "../../../../api/context/addressChannels";
import { GoalCompletionListener, GoalCompletionListenerInvocation } from "../../../../api/listener/GoalsSetListener";
import { SdmGoal } from "../../../../ingesters/sdmGoalIngester";
import { fetchCommitForSdmGoal, fetchGoalsForCommit } from "../../../../internal/delivery/goals/support/fetchGoalsOnCommit";
import { RepoRefResolver } from "../../../../spi/repo-ref/RepoRefResolver";
import { OnAnyCompletedSdmGoal } from "../../../../typings/types";
/**
* Respond to a failure or success status by running listeners
*/
@EventHandler("Run a listener on goal failure or success", subscription("OnAnyCompletedSdmGoal"))
export class RespondOnGoalCompletion implements HandleEvent {
@Value("token")
public token: string;
constructor(private readonly repoRefResolver: RepoRefResolver,
private readonly credentialsFactory: CredentialsResolver,
private readonly goalCompletionListeners: GoalCompletionListener[]) {
}
public async handle(event: EventFired,
context: HandlerContext): Promise {
const sdmGoal: SdmGoal = event.data.SdmGoal[0] as SdmGoal;
if (!isGoalRelevant(sdmGoal)) {
logger.debug(`Goal ${sdmGoal.name} skipped because not relevant for this SDM`);
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventFired, EventHandler, HandleEvent, HandlerContext, HandlerResult, Success } from "@atomist/automation-client";
import { subscription } from "@atomist/automation-client/graph/graphQL";
import { addressChannelsFor } from "../../../api/context/addressChannels";
import { ClosedIssueListener, ClosedIssueListenerInvocation } from "../../../api/listener/ClosedIssueListener";
import { CredentialsResolver } from "../../../spi/credentials/CredentialsResolver";
import { RepoRefResolver } from "../../../spi/repo-ref/RepoRefResolver";
import * as schema from "../../../typings/types";
/**
* A new issue has been created.
*/
@EventHandler("On an issue being closed", subscription("OnClosedIssue"))
export class ClosedIssueHandler implements HandleEvent {
private readonly closedIssueListeners: ClosedIssueListener[];
constructor(closedIssueListeners: ClosedIssueListener[],
private readonly repoRefResolver: RepoRefResolver,
private readonly credentialsFactory: CredentialsResolver) {
this.closedIssueListeners = closedIssueListeners;
}
public async handle(event: EventFired,
context: HandlerContext,
params: this): Promise {
const issue = event.data.Issue[0];
const id = params.repoRefResolver.toRemoteRepoRef(issue.repo, {});
const credentials = this.credentialsFactory.eventHandlerCredentials(context, id);
constructor(private readonly implementationMapper: SdmGoalImplementationMapper,
private readonly projectLoader: ProjectLoader,
private readonly repoRefResolver: RepoRefResolver,
private readonly credentialsResolver: CredentialsResolver,
private readonly logFactory: ProgressLogFactory) {
const implementationName = "FulfillGoal";
this.subscriptionName = "OnAnyRequestedSdmGoal";
this.subscription =
subscription({name: "OnAnyRequestedSdmGoal"});
this.name = implementationName + "OnAnyRequestedSdmGoal";
this.description = `Fulfill a goal when it reaches 'requested' state`;
}
import * as _ from "lodash";
import { addressChannelsFor } from "../../../../api/context/addressChannels";
import {
FingerprintDifference,
FingerprintDifferenceListener,
FingerprintDifferenceListenerInvocation,
FingerprintValue,
} from "../../../../api/listener/FingerprintDifferenceListener";
import { CredentialsResolver } from "../../../../spi/credentials/CredentialsResolver";
import { RepoRefResolver } from "../../../../spi/repo-ref/RepoRefResolver";
import * as schema from "../../../../typings/types";
/**
* React to a PushImpact event to react to semantic diffs
*/
@EventHandler("Find semantic diffs from a PushImpact", subscription("OnPushImpact"))
export class ReactToSemanticDiffsOnPushImpact
implements HandleEvent {
constructor(private readonly differenceListeners: FingerprintDifferenceListener[],
private readonly repoRefResolver: RepoRefResolver,
private readonly credentialsFactory: CredentialsResolver) {
}
public async handle(event: EventFired,
context: HandlerContext,
params: this): Promise {
const pushImpact = event.data.PushImpact[0];
const after = pushImpact.push.after;
const id = params.repoRefResolver.toRemoteRepoRef(after.repo, { sha: after.sha });
export interface EndpointVerificationInvocation extends ListenerInvocation {
/**
* Reported endpoint base url
*/
url: string;
}
export type EndpointVerificationListener = SdmListener;
/**
* React to an endpoint reported in a GitHub status.
*/
@EventHandler("React to an endpoint",
subscription({
name: "OnSuccessStatus",
variables: {
context: StagingEndpointContext,
},
}),
)
export class OnEndpointStatus implements HandleEvent {
@Secret(Secrets.OrgToken)
private githubToken: string;
constructor(public goal: Goal, private sdm: SdmVerification) {
}
public async handle(event: EventFired,
context: HandlerContext,
import { subscription } from "@atomist/automation-client/graph/graphQL";
import * as _ from "lodash";
import {
FingerprintDifference,
FingerprintDifferenceInvocation,
FingerprintDifferenceListener,
FingerprintValue,
} from "../../../../common/listener/FingerprintDifferenceListener";
import { addressChannelsFor } from "../../../../common/slack/addressChannels";
import * as schema from "../../../../typings/types";
import { toRemoteRepoRef } from "../../../../util/git/repoRef";
/**
* React to a PushImpact event to react to semantic diffs
*/
@EventHandler("Find semantic diffs from a PushImpact", subscription("OnPushImpact"))
export class ReactToSemanticDiffsOnPushImpact
implements HandleEvent {
@Secret(Secrets.OrgToken)
private readonly githubToken: string;
constructor(private readonly differenceListeners: FingerprintDifferenceListener[]) {
}
public async handle(event: EventFired,
context: HandlerContext,
params: this): Promise {
const pushImpact = event.data.PushImpact[0];
const after = pushImpact.push.after;
const id = toRemoteRepoRef(after.repo, { sha: after.sha });