chore: migrate gitpod -> ona (#62046)

This commit is contained in:
Shaun Hamilton
2025-09-12 09:34:52 +02:00
committed by GitHub
parent 003807217a
commit af730bf585
23 changed files with 313 additions and 169 deletions

View File

@@ -5,7 +5,7 @@ Checklist:
- [ ] I have read and followed the [contribution guidelines](https://contribute.freecodecamp.org).
- [ ] I have read and followed the [how to open a pull request guide](https://contribute.freecodecamp.org/how-to-open-a-pull-request/).
- [ ] My pull request targets the `main` branch of freeCodeCamp.
- [ ] I have tested these changes either locally on my machine, or Gitpod.
- [ ] I have tested these changes either locally on my machine, or Ona.
<!--If your pull request closes a GitHub issue, replace the XXXXX below with the issue number.-->

View File

@@ -3,7 +3,7 @@
[![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://makeapullrequest.com)
[![first-timers-only Friendly](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](https://www.firsttimersonly.com/)
[![Open Source Helpers](https://www.codetriage.com/freecodecamp/freecodecamp/badges/users.svg)](https://www.codetriage.com/freecodecamp/freecodecamp)
[![Setup Automated](https://img.shields.io/badge/setup-automated-blue?logo=gitpod)](https://gitpod.io/from-referrer/)
[![Setup Automated](https://img.shields.io/badge/setup-automated-blue?logo=ona)](https://ona.com/from-referrer/)
[![Discord](https://img.shields.io/discord/692816967895220344?logo=discord&label=Discord&color=5865F2)](https://discord.gg/PRyKn3Vbay)
## freeCodeCamp.org's open-source codebase and curriculum

View File

@@ -527,20 +527,23 @@
"project-preview-title": "Here's a preview of what you will build",
"demo-project-title": "Here's an example of a project that meets the requirements",
"github-required": "<0>Create a GitHub</0> account if you don't have one. You'll need it when you create the virtual Linux server machine. This process may take a few minutes.",
"gitpod": {
"intro": "This course runs in a virtual Linux machine using Gitpod. Follow these instructions to start the course:",
"step-1": "<0>Create a GitHub</0> account if you don't have one",
"ona": {
"intro": "This course runs in a virtual Linux machine using Ona. Follow these instructions to start the course:",
"step-1": "<0>Create an Ona account</0> if you don't have one",
"step-2": "Click the start button below",
"step-3": "Login to Gitpod with your GitHub account if you aren't already",
"step-3": "In the modal that pops up, click the create button",
"step-4": "Once the virtual Linux machine is finished loading, start the CodeRoad extension by:",
"step-5": "Clicking the \"hamburger\" menu near the top left of the VSCode window,",
"step-6": "Going to the \"View\" menu,",
"step-7": "Clicking on the \"Command Palette\" option,",
"step-8": "and running the \"CodeRoad: Start\" command",
"step-6": "Going to the <0>View</0> menu,",
"step-7": "Clicking on the <0>Command Palette</0> option,",
"step-8": "and running the <0>CodeRoad: Start</0> command",
"step-9": "Follow the instructions in CodeRoad to complete the course",
"continue-project": "Clicking the button below will start a new project. If you have previously started the {{course}} course, go to <0>your Gitpod dashboard</0> to continue.",
"learn-more": "Learn more about <0>Gitpod workspaces.</0>",
"logout-warning": "If you log out of freeCodeCamp before you complete the entire {{course}} course, your progress will not be saved to your freeCodeCamp account."
"continue-project": "Clicking the button below will start a new project. If you have previously started the {{course}} course, go to <0>your Ona dashboard</0> to continue.",
"learn-more": "Learn more about <0>Ona workspaces.</0>",
"logout-warning": "If you log out of freeCodeCamp before you complete the entire {{course}} course, your progress will not be saved to your freeCodeCamp account.",
"sub-step-3": "Navigate to your <0>Ona secrets page</0>",
"sub-step-4": "Create a new secret named <0>CODEROAD_WEBHOOK_TOKEN</0>",
"sub-step-5": "In the <0>Secret</0> field, paste your token"
},
"local": {
"intro": "This course runs in a virtual Linux machine on your computer. To run the course, you first need to download each of the following if you don't already have them:",

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { Trans } from 'react-i18next';
import { isPrivate } from './form-ip-utils';
// Matches editor links for: Replit, Glitch, CodeSandbox, GitHub. NOT Codespaces, and NOT Gitpod yet
// Matches editor links for: Replit, Glitch, CodeSandbox, GitHub. NOT Codespaces, and NOT Gitpod/Ona yet
// Once safari allows negative lookbehinds, this can be used:
// |(?<!\.app)\.github\.dev
const editorRegex =

View File

@@ -5,25 +5,23 @@ import { useFeatureValue } from '@growthbook/growthbook-react';
import { SuperBlocks } from '../../../../shared/config/curriculum';
import { Link } from '../helpers';
type GitpodNoteProps = {
type OnaNoteProps = {
superBlock: SuperBlocks;
};
export function GitpodNote({
superBlock
}: GitpodNoteProps): JSX.Element | null {
const gitpodNoteFeature = useFeatureValue<{
export function OnaNote({ superBlock }: OnaNoteProps): JSX.Element | null {
const onaNoteFeature = useFeatureValue<{
superblocks: string[];
}>('gitpod-note', { superblocks: [] });
const { t } = useTranslation();
return gitpodNoteFeature.superblocks.includes(superBlock) ? (
return onaNoteFeature.superblocks.includes(superBlock) ? (
<Alert variant='info'>
<p>
<Link
external={true}
sameTab={false}
to='https://forum.freecodecamp.org/t/using-gitpod-in-the-curriculum/668669'
to='https://forum.freecodecamp.org/t/relational-database-curriculum-in-ona/760889'
>
{t('intro:misc-text.read-database-cert-article')}
</Link>

View File

@@ -1,39 +0,0 @@
import React from 'react';
import { Trans } from 'react-i18next';
import { Alert, Spacer } from '@freecodecamp/ui';
interface RdbGitpodContinueAlertProps {
course: string;
}
function RdbGitpodContinueAlert({
course
}: RdbGitpodContinueAlertProps): JSX.Element {
return (
<Alert variant='info'>
<Trans values={{ course }} i18nKey='learn.gitpod.continue-project'>
<a
href='https://gitpod.io/workspaces'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
<Spacer size='m' />
<Trans i18nKey='learn.gitpod.learn-more'>
<a
href='https://forum.freecodecamp.org/t/using-gitpod-in-the-curriculum/668669'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
</Alert>
);
}
RdbGitpodContinueAlert.displayName = 'RdbGitpodContinueAlert';
export default RdbGitpodContinueAlert;

View File

@@ -1,42 +0,0 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
function RdbGitpodInstructions(): JSX.Element {
const { t } = useTranslation();
return (
<div className='ca-description'>
<p>{t('learn.gitpod.intro')}</p>
<ol>
<li>
<Trans i18nKey='learn.gitpod.step-1'>
<a
href='https://github.com/join'
rel='noopener noreferrer'
target='_blank'
title={t('learn.source-code-link')}
>
placeholder
</a>
</Trans>
</li>
<li>{t('learn.gitpod.step-2')}</li>
<li>{t('learn.gitpod.step-3')}</li>
<li>
{t('learn.gitpod.step-4')}
<ul>
<li>{t('learn.gitpod.step-5')}</li>
<li>{t('learn.gitpod.step-6')}</li>
<li>{t('learn.gitpod.step-7')}</li>
<li>{t('learn.gitpod.step-8')}</li>
</ul>
</li>
<li>{t('learn.gitpod.step-9')}</li>
</ol>
</div>
);
}
RdbGitpodInstructions.displayName = 'RdbGitpodInstructions';
export default RdbGitpodInstructions;

View File

@@ -1,23 +0,0 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Alert } from '@freecodecamp/ui';
interface RdbGitpodLogoutAlertProps {
course: string;
}
function RdbGitpodLogoutAlert({
course
}: RdbGitpodLogoutAlertProps): JSX.Element {
const { t } = useTranslation();
return (
<Alert variant='danger'>
{t('learn.gitpod.logout-warning', { course })}
</Alert>
);
}
RdbGitpodLogoutAlert.displayName = 'RdbGitpodLogoutAlert';
export default RdbGitpodLogoutAlert;

View File

@@ -0,0 +1,35 @@
import React from 'react';
import { Trans } from 'react-i18next';
import { Alert, Spacer } from '@freecodecamp/ui';
interface RdbOnaContinueAlertProps {
course: string;
}
function RdbOnaContinueAlert({
course
}: RdbOnaContinueAlertProps): JSX.Element {
return (
<Alert variant='info'>
<Trans values={{ course }} i18nKey='learn.ona.continue-project'>
<a href='https://app.ona.com' rel='noopener noreferrer' target='_blank'>
placeholder
</a>
</Trans>
<Spacer size='m' />
<Trans i18nKey='learn.ona.learn-more'>
<a
href='https://forum.freecodecamp.org/t/relational-database-curriculum-in-ona/760889'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
</Alert>
);
}
RdbOnaContinueAlert.displayName = 'RdbOnaContinueAlert';
export default RdbOnaContinueAlert;

View File

@@ -0,0 +1,205 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { Spacer, Button } from '@freecodecamp/ui';
import { postUserToken } from '../../../utils/ajax';
import { createFlashMessage } from '../../../components/Flash/redux';
import { FlashMessages } from '../../../components/Flash/redux/flash-messages';
import {
isSignedInSelector,
userTokenSelector
} from '../../../redux/selectors';
import { updateUserToken } from '../../../redux/actions';
import RdbLocalLogoutAlert from './rdb-local-logout-alert';
const mapStateToProps = (state: unknown) => ({
isSignedIn: isSignedInSelector(state),
userToken: userTokenSelector(state) as string | null
});
const mapDispatchToProps = {
createFlashMessage,
updateUserToken
};
interface RdbOnaInstructionsProps {
course: string;
createFlashMessage: typeof createFlashMessage;
isSignedIn: boolean;
updateUserToken: (arg0: string) => void;
url: string;
userToken: string | null;
}
function RdbOnaInstructions({
course,
createFlashMessage,
isSignedIn,
updateUserToken,
url,
userToken
}: RdbOnaInstructionsProps): JSX.Element {
const { t } = useTranslation();
const coderoadTutorial = `https://raw.githubusercontent.com/${url}/main/tutorial.json`;
const generateUserToken = async () => {
const createUserTokenResponse = await postUserToken();
const { data = { userToken: null } } = createUserTokenResponse;
if (data?.userToken) {
updateUserToken(data.userToken);
createFlashMessage({
type: 'success',
message: FlashMessages.UserTokenGenerated
});
} else {
createFlashMessage({
type: 'danger',
message: FlashMessages.UserTokenGenerateError
});
}
};
const copyUserToken = () => {
navigator.clipboard.writeText(userToken ?? '').then(
() => {
createFlashMessage({
type: 'success',
message: FlashMessages.UserTokenCopied
});
},
() => {
createFlashMessage({
type: 'danger',
message: FlashMessages.UserTokenCopyError
});
}
);
};
const copyUrl = () => {
navigator.clipboard.writeText(coderoadTutorial ?? '').then(
() => {
createFlashMessage({
type: 'success',
message: FlashMessages.CourseUrlCopied
});
},
() => {
createFlashMessage({
type: 'danger',
message: FlashMessages.CourseUrlCopyError
});
}
);
};
return (
<div className='ca-description'>
<p>{t('learn.ona.intro')}</p>
<ol>
<li>
<Trans i18nKey='learn.ona.step-1'>
<a
href='https://app.ona.com/login?navigateTo=%2Fsettings%2Fsecrets'
rel='noopener noreferrer'
target='_blank'
>
placeholder
</a>
</Trans>
</li>
{isSignedIn && (
<>
<Spacer size='s' />
<p>{t('learn.local.sub-step-heading')}</p>
<ol>
<li>{t('learn.local.sub-step-1')}</li>
<Spacer size='xxs' />
<Button
disabled={!!userToken}
block={true}
onClick={() => void generateUserToken()}
>
{t('learn.local.generate-token-btn')}
</Button>
<Spacer size='xs' />
<li>{t('learn.local.sub-step-2')}</li>
<Spacer size='xxs' />
<Button
disabled={!userToken}
block={true}
onClick={copyUserToken}
>
{t('learn.local.copy-token-btn')}
</Button>
<Spacer size='xs' />
<li>
<Trans i18nKey='learn.ona.sub-step-3'>
<a
href='https://app.ona.com/settings/secrets'
rel='noopener noreferrer'
target='_blank'
>
Ona secrets page
</a>
</Trans>
</li>
<li>
<Trans i18nKey='learn.ona.sub-step-4'>
<code>placeholder</code>
</Trans>
</li>
<li>
<Trans i18nKey='learn.ona.sub-step-5'>
<code>placeholder</code>
</Trans>
</li>
<Spacer size='xs' />
<RdbLocalLogoutAlert course={course} />
</ol>
<Spacer size='s' />
</>
)}
<li>{t('learn.ona.step-2')}</li>
<li>{t('learn.ona.step-3')}</li>
<li>
{t('learn.ona.step-4')}
<ul>
<li>{t('learn.ona.step-5')}</li>
<li>
<Trans i18nKey='learn.ona.step-6'>
<code>placeholder</code>
</Trans>
</li>
<li>
<Trans i18nKey='learn.ona.step-7'>
<code>placeholder</code>
</Trans>
</li>
<li>
<Trans i18nKey='learn.ona.step-8'>
<code>placeholder</code>
</Trans>
</li>
<li>{t('learn.local.step-7')}</li>
<Spacer size='xxs' />
<Button block={true} onClick={copyUrl}>
{t('learn.local.copy-url')}
</Button>
<Spacer size='xs' />
<li>{t('learn.local.step-8')}</li>
</ul>
</li>
<li>{t('learn.ona.step-9')}</li>
</ol>
</div>
);
}
RdbOnaInstructions.displayName = 'RdbOnaInstructions';
export default connect(mapStateToProps, mapDispatchToProps)(RdbOnaInstructions);

View File

@@ -0,0 +1,19 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Alert } from '@freecodecamp/ui';
interface RdbOnaLogoutAlertProps {
course: string;
}
function RdbOnaLogoutAlert({ course }: RdbOnaLogoutAlertProps): JSX.Element {
const { t } = useTranslation();
return (
<Alert variant='danger'>{t('learn.ona.logout-warning', { course })}</Alert>
);
}
RdbOnaLogoutAlert.displayName = 'RdbOnaLogoutAlert';
export default RdbOnaLogoutAlert;

View File

@@ -50,9 +50,9 @@ import { CodeAllyDown } from '../../../components/growth-book/codeally-down';
import { postUserToken } from '../../../utils/ajax';
import { CodeAllyButton } from '../../../components/growth-book/codeally-button';
import RdbGitpodContinueAlert from './rdb-gitpod-continue-alert';
import RdbGitpodInstructions from './rdb-gitpod-instructions';
import RdbGitpodLogoutAlert from './rdb-gitpod-logout-alert';
import RdbOnaContinueAlert from './rdb-ona-continue-alert';
import RdbOnaInstructions from './rdb-ona-instructions';
import RdbOnaLogoutAlert from './rdb-ona-logout-alert';
import RdbLocalInstructions from './rdb-local-instructions';
import RdbStep1Instructions from './rdb-step-1-instructions';
import RdbStep2Instructions from './rdb-step-2-instructions';
@@ -191,38 +191,26 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const openGitpod = (userToken?: string) => {
const {
data: {
challengeNode: {
challenge: { url }
}
}
} = props;
function openOna() {
const repoUrl = `https://github.com/freeCodeCamp/rdb-alpha`;
const onaDomain = `https://app.ona.com/`;
const onaUrl = `${onaDomain}#${repoUrl}`;
const repoUrl = `https://github.com/${url}`;
const coderoadTutorial = encodeURIComponent(
`https://raw.githubusercontent.com/${url}/main/tutorial.json`
);
const gitpodDomain = `https://gitpod.io/?autostart=true#CODEROAD_TUTORIAL_URL=${coderoadTutorial},CODEROAD_DISABLE_RUN_ON_SAVE=true`;
const tokenEnv = userToken ? `,CODEROAD_WEBHOOK_TOKEN=${userToken}` : '';
const gitpodUrl = `${gitpodDomain}${tokenEnv}/${repoUrl}`;
window.open(gitpodUrl, '_blank');
};
window.open(onaUrl, '_blank');
}
const startCourse = async () => {
const { isSignedIn, userToken, updateUserToken } = props;
if (!isSignedIn) {
openGitpod();
openOna();
} else if (!userToken) {
const createUserTokenResponse = await postUserToken();
const { data = { userToken: null } } = createUserTokenResponse;
if (data?.userToken) {
updateUserToken(data.userToken);
openGitpod(data.userToken);
openOna();
} else {
createFlashMessage({
type: 'danger',
@@ -230,7 +218,7 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
});
}
} else {
openGitpod(userToken);
openOna();
}
};
@@ -269,7 +257,7 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
}
};
const gitpodDeprecated = useFeature('gitpod-deprecated').on;
const onaDeprecated = useFeature('gitpod-deprecated').on;
return (
<Hotkeys containerRef={container}>
@@ -291,7 +279,7 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
<PrismFormatted text={description} />
<Spacer size='m' />
{gitpodDeprecated ? (
{onaDeprecated ? (
<>
<RdbLocalInstructions course={title} url={url} />
<Spacer size='m' />
@@ -325,7 +313,7 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
</>
) : (
<>
<RdbGitpodInstructions />
<RdbOnaInstructions course={title} url={url} />
<Spacer size='m' />
{isSignedIn &&
challengeType === challengeTypes.codeAllyCert ? (
@@ -340,8 +328,8 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
isCompleted={isPartiallyCompleted || isCompleted}
/>
<Spacer size='m' />
<RdbGitpodContinueAlert course={title} />
{isSignedIn && <RdbGitpodLogoutAlert course={title} />}
<RdbOnaContinueAlert course={title} />
{isSignedIn && <RdbOnaLogoutAlert course={title} />}
<CodeAllyButton
challengeType={challengeType}
//eslint-disable-next-line @typescript-eslint/no-misused-promises
@@ -363,8 +351,8 @@ function ShowCodeAlly(props: ShowCodeAllyProps) {
</>
) : (
<>
<RdbGitpodContinueAlert course={title} />
{isSignedIn && <RdbGitpodLogoutAlert course={title} />}
<RdbOnaContinueAlert course={title} />
{isSignedIn && <RdbOnaLogoutAlert course={title} />}
<CodeAllyButton
challengeType={challengeType}
//eslint-disable-next-line @typescript-eslint/no-misused-promises

View File

@@ -11,7 +11,7 @@ import { Link } from '../../../components/helpers';
import { CodeAllyDown } from '../../../components/growth-book/codeally-down';
import envData from '../../../../config/env.json';
import { GitpodNote } from '../../../components/growth-book/gitpod-note';
import { OnaNote } from '../../../components/growth-book/ona-note';
const { clientLocale } = envData;
@@ -51,7 +51,7 @@ function LegacyLinks({ superBlock }: LegacyLinksProps): JSX.Element {
</Alert>
);
} else {
return <GitpodNote superBlock={superBlock} />;
return <OnaNote superBlock={superBlock} />;
}
}

View File

@@ -8,7 +8,7 @@ dashedName: mean-variance-standard-deviation-calculator
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:
@@ -53,7 +53,7 @@ For example, `calculate([0,1,2,3,4,5,6,7,8])` should return:
## Development
Write your code in `mean_var_std.py`. For development, you can use `main.py` to test your code. In
order to run your code, type `python3 main.py` into the GitPod terminal and hit enter. This will cause the included CPython interpreter to run the `main.py` file.
order to run your code, type `python3 main.py` into the Ona terminal and hit enter. This will cause the included CPython interpreter to run the `main.py` file.
## Testing

View File

@@ -8,7 +8,7 @@ dashedName: demographic-data-analyzer
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-demographic-data-analyzer/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-demographic-data-analyzer/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:

View File

@@ -8,7 +8,7 @@ dashedName: medical-data-visualizer
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-medical-data-visualizer/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-medical-data-visualizer/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:

View File

@@ -8,7 +8,7 @@ dashedName: page-view-time-series-visualizer
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-page-view-time-series-visualizer" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-page-view-time-series-visualizer" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:

View File

@@ -8,7 +8,7 @@ dashedName: sea-level-predictor
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-sea-level-predictor/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-sea-level-predictor/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:

View File

@@ -9,7 +9,7 @@ dashedName: port-scanner
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-port-scanner" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>. Learn <a href="https://forum.freecodecamp.org/t/how-to-use-gitpod-in-the-curriculum/668669#how-can-i-share-my-workspace-to-get-help-8" target="_blank" rel="noopener noreferrer nofollow">how to share your Gitpod workspace to get help</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-port-scanner" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:

View File

@@ -9,7 +9,7 @@ dashedName: sha-1-password-cracker
# --description--
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-SHA-1-password-cracker" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a> Learn <a href="https://forum.freecodecamp.org/t/how-to-use-gitpod-in-the-curriculum/668669#how-can-i-share-my-workspace-to-get-help-8" target="_blank" rel="noopener noreferrer nofollow">how to share your Gitpod workspace to get help</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-SHA-1-password-cracker" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:

View File

@@ -37,7 +37,7 @@ Replit is an online platform that provides a collaborative environment for codin
Another popular cloud-based editor is GitHub Codespaces. This is a cloud-based development environment that provides instant access to a fully-configured code editor and development tools directly from GitHub, enabling seamless coding and collaboration.
And another one is Gitpod. Gitpod is a cloud-based development environment that integrates with GitHub and GitLab, offering instant, customizable workspaces for coding, building, and debugging directly from your browser.
And another one is Ona. Ona is a cloud-based development environment that integrates with GitHub and GitLab, offering instant, customizable workspaces for coding, building, and debugging directly from your browser.
And there are many more options. Some options, such as Visual Studio Code, are highly extensible and can work with multiple different project types and languages. Other options might be specifically tailored to a small subset of languages or project types.
@@ -103,7 +103,7 @@ The lecture lists several cloud-based options, but one popular editor is primari
---
Gitpod
Ona
### --feedback--

View File

@@ -10,7 +10,7 @@ dashedName: rock-paper-scissors
For this challenge, you will create a program to play Rock, Paper, Scissors. A program that picks at random will usually win 50% of the time. To pass this challenge your program must play matches against four different bots, winning at least 60% of the games in each match.
You will be <a href="https://gitpod.io/?autostart=true#https://github.com/freeCodeCamp/boilerplate-rock-paper-scissors/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Gitpod starter code</a>.
You will be <a href="https://app.ona.com/?autostart=true#https://github.com/freeCodeCamp/boilerplate-rock-paper-scissors/" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Ona starter code</a>.
We are still developing the interactive instructional part of the machine learning curriculum. For now, you will have to use other resources to learn how to pass this challenge.

View File

@@ -695,7 +695,7 @@ BitBucket
#### --answer--
Gitpod
Ona
### --question--