Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature:pipeline-support #1211

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/api/session/SessionManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AuthProviderBase, AuthProviders } from '../../lib/auth/AuthProviders'
import { ApiTokenAuthenticator } from '../../lib/auth/AuthProviders/ApiTokenAuthenticator'
import { Token } from '../../lib/auth/Token'
import { VTEXID } from '../clients/IOClients/external/VTEXID'
import { ErrorKinds } from '../error/ErrorKinds'
Expand All @@ -21,6 +22,14 @@ export interface LoginInput {
workspaceCreation: WorkspaceCreation
}


export interface PipelineLoginInput {
vtexApiKey?: string
vtexApiToken?: string
targetWorkspace: string
workspaceCreation: WorkspaceCreation
}

export interface WorkspaceSwitchInput {
targetWorkspace: string
workspaceCreation: WorkspaceCreation
Expand Down Expand Up @@ -151,6 +160,37 @@ export class SessionManager implements ISessionManager {
})
}


public async loginUsingPipeline(newAccount: string, {
vtexApiKey,
targetWorkspace = 'master',
workspaceCreation,
vtexApiToken
}: PipelineLoginInput) {
if (this.account !== newAccount) {
this.state.lastAccount = this.account
this.state.lastWorkspace = null
}

const cachedToken = new Token(this.sessionPersister.getAccountToken(newAccount))

if (cachedToken.isValid()) {
this.state.tokenObj = cachedToken
} else {
const apiToken = new ApiTokenAuthenticator()
const token = await apiToken.login(vtexApiKey, vtexApiToken, newAccount)
this.state.tokenObj = new Token(token)
this.sessionPersister.saveAccountToken(newAccount, this.state.tokenObj.token)
}


this.state.account = newAccount
this.state.workspace = 'master'
this.saveState()
await this.workspaceSwitch({ targetWorkspace, workspaceCreation })
}


public async login(
newAccount: string,
{ targetWorkspace = 'master', authMethod = 'oauth', useCachedToken = true, workspaceCreation }: LoginInput
Expand Down
8 changes: 6 additions & 2 deletions src/commands/deprecate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export default class Deprecate extends CustomCommand {
static flags = {
...CustomCommand.globalFlags,
yes: oclifFlags.boolean({ description: 'Answers yes to all prompts.', char: 'y', default: false }),
pipeline: oclifFlags.boolean({
char: 'p',
description: `Runs the command in ${ColorifyConstants.ID('pipeline')} mode.`,
})
}

static strict = false
Expand All @@ -41,11 +45,11 @@ export default class Deprecate extends CustomCommand {
async run() {
const {
raw,
flags: { yes },
flags: { yes, pipeline },
} = this.parse(Deprecate)

const allArgs = this.getAllArgs(raw)

await appsDeprecate(allArgs, { yes })
await appsDeprecate(allArgs, { yes }, pipeline)
}
}
21 changes: 19 additions & 2 deletions src/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CustomCommand } from '../api/oclif/CustomCommand'
import authLogin from '../modules/auth/login'

import { ColorifyConstants } from '../api/constants/Colors'
import loginWithPipeline from '../modules/auth/pipeline'

export default class Login extends CustomCommand {
static description = `Logs in to a ${ColorifyConstants.ID('VTEX account')}.`
Expand All @@ -15,10 +16,22 @@ export default class Login extends CustomCommand {

static flags = {
...CustomCommand.globalFlags,
pipeline: oclifFlags.boolean({
char: 'p',
description: `Runs the command in ${ColorifyConstants.ID('pipeline')} mode.`,
}),
workspace: oclifFlags.string({
char: 'w',
description: `Logs in the specified ${ColorifyConstants.ID('workspace')}.`,
}),
vtexApiKey: oclifFlags.string({
char: 'k',
description: `VTEX API Key.`,
}),
vtexApiToken: oclifFlags.string({
char: 't',
description: `VTEX API`
})
}

static args = [
Expand All @@ -28,9 +41,13 @@ export default class Login extends CustomCommand {
async run() {
const {
args: { account },
flags: { workspace },
flags: { workspace, pipeline, vtexApiKey, vtexApiToken },
} = this.parse(Login)

await authLogin({ account, workspace })
if(!pipeline) {
await authLogin({ account, workspace })
}else{
await loginWithPipeline({ account, workspace }, vtexApiKey, vtexApiToken)
}
}
}
8 changes: 6 additions & 2 deletions src/commands/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export default class Publish extends CustomCommand {
char: 'w',
description: `Uses the specified ${ColorifyConstants.ID('workspace')} in the app registry.`,
}),
pipeline: oclifFlags.boolean({
char: 'p',
description: `Runs the command in ${ColorifyConstants.ID('pipeline')} mode.`,
}),
force: oclifFlags.boolean({
char: 'f',
description: 'Publishes the app independently of SemVer rules.',
Expand All @@ -27,9 +31,9 @@ export default class Publish extends CustomCommand {
async run() {
const {
args: { path },
flags: { yes, workspace, force, tag },
flags: { yes, workspace, force, tag, pipeline },
} = this.parse(Publish)

await appsPublish(path, { yes, workspace, force, tag })
await appsPublish(path, { yes, workspace, force, tag }, pipeline)
}
}
9 changes: 7 additions & 2 deletions src/commands/release.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { flags as oclifFlags } from '@oclif/command'
import { CustomCommand } from '../api/oclif/CustomCommand'
import appsRelease, { releaseTypeAliases, supportedReleaseTypes, supportedTagNames } from '../modules/release'

Expand All @@ -17,6 +18,10 @@ export default class Release extends CustomCommand {

static flags = {
...CustomCommand.globalFlags,
pipeline: oclifFlags.boolean({
char: 'p',
description: `Runs the command in ${ColorifyConstants.ID('pipeline')} mode.`,
})
}

static args = [
Expand All @@ -32,9 +37,9 @@ export default class Release extends CustomCommand {

async run() {
const {
flags: { pipeline },
args: { releaseType, tagName },
} = this.parse(Release)

await appsRelease(releaseType, tagName)
await appsRelease(releaseType, tagName, pipeline)
}
}
38 changes: 38 additions & 0 deletions src/lib/auth/AuthProviders/ApiTokenAuthenticator/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import axios from 'axios'

export class ApiTokenAuthenticator {
public async login(apiKey: string, apiToken: string, account: string) {
const url = `https://api.vtexcommercestable.com.br/api/vtexid/apptoken/login?an=${account}`

const body = {
appKey: apiKey,
appToken: apiToken
}

try{
const response = await axios.post(url, body, {
headers: {
'Content-Type': 'application/json'
}
})

if(response.status === 200){
const { data } = response

if(data?.token){
const token = data.token
return token
}else{
throw new Error('Invalid credentials')
}

}else{
throw new Error('Invalid credentials')
}


}catch(error){
throw new Error(error)
}
}
}
9 changes: 6 additions & 3 deletions src/modules/apps/deprecate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const prepareAndDeprecateApps = async (appsList: string[]): Promise<any> => {
await returnToPreviousAccount({ previousAccount: originalAccount, previousWorkspace: originalWorkspace })
}

export default async (optionalApps: string[], options) => {
export default async (optionalApps: string[], options, pipeline: boolean = false) => {
const preConfirm = options.y || options.yes

const { account, workspace } = SessionManager.getSingleton()
Expand All @@ -79,9 +79,12 @@ export default async (optionalApps: string[], options) => {

const appsList = optionalApps.length > 0 ? optionalApps : [(await ManifestEditor.getManifestEditor()).appLocator]

if (!preConfirm && !(await promptDeprecate(appsList))) {
return
if(!pipeline){
if (!preConfirm && !(await promptDeprecate(appsList))) {
return
}
}


log.debug(`Deprecating app${appsList.length > 1 ? 's' : ''}: ${appsList.join(', ')}`)
return prepareAndDeprecateApps(appsList)
Expand Down
4 changes: 2 additions & 2 deletions src/modules/apps/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const publisher = (workspace = 'master') => {
return { publishApp, publishApps }
}

export default async (path: string, options) => {
export default async (path: string, options, pipeline: boolean) => {
log.debug(`Starting to publish app in ${conf.getEnvironment()}`)

const { account } = SessionManager.getSingleton()
Expand All @@ -136,7 +136,7 @@ export default async (path: string, options) => {

const yesFlag = options.y || options.yes

if (!yesFlag) {
if (!pipeline && !yesFlag) {
const confirmVersion = await promptConfirm(
`Are you sure that you want to release version ${chalk.bold(`${versionMsg} of ${appNameMsg}?`)}`,
false
Expand Down
2 changes: 1 addition & 1 deletion src/modules/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export interface LoginOptions {
postLoginOps?: PostLoginOps[]
}

const getTargetLogin = async ({ account: optionAccount, workspace: optionWorkspace }: LoginOptions) => {
export const getTargetLogin = async ({ account: optionAccount, workspace: optionWorkspace }: LoginOptions) => {
const {
account: previousAccount,
workspace: previousWorkspace,
Expand Down
58 changes: 58 additions & 0 deletions src/modules/auth/pipeline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { SessionManager } from '../../api/session/SessionManager'
import { handleErrorCreatingWorkspace, workspaceCreator } from '../../api/modules/workspace/create'
import log from '../../api/logger'

const vtexApiKeyLabel = 'VTEX_API_KEY';
const vtexApiTokenLabel = 'VTEX_API_TOKEN';

export interface LoginOptions {
account?: string
workspace?: string
}

export default async (opts: LoginOptions, vtexApiKey?: string, vtexApiToken?: string) => {
if (!vtexApiKey || !vtexApiToken || !opts.account) {
const credentials = getCredentialsInEnvirovmentVariables();
if (credentials) {
vtexApiKey = credentials.vtexApiKey;
vtexApiToken = credentials.vtexApiToken;
const sessionManager = SessionManager.getSingleton()
await sessionManager.loginUsingPipeline(
opts.account,
{
vtexApiKey,
targetWorkspace: opts.workspace,
workspaceCreation: {
promptCreation: true,
creator: workspaceCreator,
onError: handleErrorCreatingWorkspace,
},
vtexApiToken
})
log.info('You are now logged in');
} else {
log.error('VTEX_API_KEY and VTEX_API_TOKEN must be provided');
}
}
}


interface credentialsType {
vtexApiKey: string,
vtexApiToken: string,
}

function getCredentialsInEnvirovmentVariables(): credentialsType | null {
try {
const vtexApiKey = process.env[vtexApiKeyLabel];
const vtexApiToken = process.env[vtexApiTokenLabel];

if (vtexApiKey && vtexApiToken) {
return { vtexApiKey, vtexApiToken };
} else {
return null;
}
} catch (error) {

}
}
14 changes: 9 additions & 5 deletions src/modules/release/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ Valid release tags are: ${supportedTagNames.join(', ')}`)

export default async (
releaseType = 'patch', // This arg. can also be a valid (semver) version.
tagName = 'beta'
tagName = 'beta',
pipeline = false
) => {
const utils = new ReleaseUtils()
utils.checkGit()
Expand All @@ -78,9 +79,12 @@ export default async (
const tagText = `v${newVersion}`
const changelogVersion = `\n\n## [${newVersion}] - ${year}-${month}-${day}`

if (!(await utils.confirmRelease())) {
// Abort release.
return

if(!pipeline){
if (!(await utils.confirmRelease())) {
// Abort release.
return
}
}
log.info('Starting release...')
try {
Expand All @@ -93,7 +97,7 @@ export default async (
await utils.commit(tagText)
await utils.tag(tagText)
await utils.push(tagText)
await utils.postRelease()
if(!pipeline) await utils.postRelease();
} catch (e) {
log.error(`Failed to release \n${e}`)
}
Expand Down