[MUSIC].
>> Everybody just tuning in, welcome.
Thank you guys so much for being here.
This is a big monorepo.
I have multiple Docker compose files I did use to deploy to swarm.
One of the ways that I did that was that I have
this deploy script here that would log into Docker with
GitLab and then do a Docker Stack deploy and that
becomes Docker compose d.production, docker-compose d.masters.
Then that gets generated out of docker
compose into a docker-compose.stack file.
Then that is what actually I would use to
run my Docker stack deploy against here.
The other thing that's going to be thrown to
the wayside is this monorepo set up.
Long story short, we're going to be removing the monorepo,
separating everything else,
and we're going to be moving everything to Azure.
Going back to the problem that I ran into the other day.
When we were working in Azure last,
you guys saw me trying to start
working with Azure's Artifacts tool.
Azure's Artifacts is essentially
the ability of taking external repositories or
registries and essentially make it so that you can
run your installs against Azure,
use Azure as that registry,
publish your own private modules
or packages or whatever to that directly.
But also what's really nice about
it is it also does caching for you.
We're going to go to Artifacts, and I'm
going to click "Create Feed" right here.
I'm going to create a Dev feed,
meaning that all of the packages pushed to this,
anything, will only be for Dev.
That's one thing I really want to note here,
which is really cool about using Azure Artifacts in feeds.
Now here's the other part I wanted to show you guys,
which is upstream sources.
When you create a feed,
they immediately say, "Hey,
do you want us to cache everything for you? We could do that."
If you check this,
it will automatically add you upstreams for NuGet, NPM, Python.
Just point your registry to Azure and start
immediately installing packages and
it will then start appearing in the list.
Boom, I'm in depth.
Now I'm going to click "Connect to Feed".
Look at this .Net, NuGet, Visual Studio,
npm, Maven, Gradle,
PIP, Twine, Universal Packages.
These are all of the managers or
package manager types that this
thing support's. I'm going to click "npm."
I want you to add the npmrc to your project.
If we go to this package we're working on right now,
I have a package.json,
but then I also have an npmrc.
Copy this in just like I have and paste it and then save it.
At that moment, if you were to do npm config get registry,
you would see that your registry is now pointed to Azure.
To know if this is working,
you should just be able to move out of the directory,
run the same command,
and you'll see bam, I'm back at registry.npm.js.
But then you have to update one more npmrc file,
which is right here in the user level.
In the user-level npmrc is literally home.
Then I do.npm, there you go.
You can see right here I have a .npmrc file right there.
I'm going to go back to Artifacts. I'm going to go to my Dev feed.
If you want to guarantee that
your packages will go to Azure the first time,
you have to get rid of the,
node modules and you have to get rid of your local cache.
There's a possibility that if you have those cache packages,
you might end up just pulling them locally,
especially if you have a shrink wrap or a yarn.lock.
Now what I'm going to do, is I'm going to do npm
install and what's going to happen is,
you see that hit right there?
That was it hitting Azure and seeing that
it needs to start downloading stuff and
Azure basically being that proxy.
You could see this first time it takes a little bit.
That's okay because what's happening is if I refresh this,
these are all of the packages that are
required for this specific shared library.
Again, remember Sentry?
All I have to do is Sentry and look,
these are all my Sentry packages. Let's do it again.
I'm going to do a rm-rf node modules,
and then I'm going to do a clear my cache.
Now watch what happens when I do it the second time.
You can immediately see it much faster now.
Before it was like [inaudible],
now it's like [inaudible].
Now that I've got that,
what I can even do is I can publish my own packages to it.
I just basically pulled in a bunch of
packages that Azure was able to proxy for me.
Remember, the goal here is I need to take this shared folder,
right here, and I need to turn it into
an npm module that I can reuse across all of my application.
We still haven't solved our main problem, which is just,
"Hey, I need to share this as a node module."
I can just do npm publish.
Now, before I do that,
let me show you what my package.json looks like.
If I go to package.json,
you're going to see that the name is using what's called a scope.
If you do both where you say,
"I'm going to make a scope package locally,
and then I'm going to make a scope package in
npm.js," they have to be or they should be the same name.
Meaning that if it's scoped in Azure,
it needs to also be scoped in npm.js' normal registry.
If it's not, you've got to basically go in and
replace all of your references
in your package.json like this here.
Now what I ran into was the second part of how all of this works.
If I go back into my feed and I click on this gear here,
you're going to notice a little feature here.
Because feeds are immutable,
deleted package versions are shown by default as a reminder that
the number is taken and can't be published again.
If I push this up to Azure Artifacts,
it's not depletable or changeable.
It's essentially 100 percent immutable.
Once you do it, it's gone.
It's there forever.
If you are not aware of
a deleted package and then you go back and say,
"Hey, I want to publish
that package or that specific number," this will fail.
This leads to the problem that I was running into the other day.
If we think about both of those things now,
which is it's immutable and when you delete stuff,
it doesn't go away forever,
it's the same thing but with regards to package upgrades.
If you want to get a newer package of
something and you want to install it through Azure,
it won't work by default.
What you have to do if you want to make sure that you
have certain dependencies that must be upgraded,
you have to go into here.
You see how this is a registry,
but look at the publisher.
I am the publisher of this.
This is the red herring here.
So unless I as a publisher have an upstream,
which I do not, this won't work.
What you have to do is you have to go into View options.
Do you see this right here? "Allow externally-sourced versions."
>This is what says, hey,
this could introduce security vulnerability issues,
and this is why this is here.
We're not going to let you by
default auto-upgrade any of your packages in your registry.
You have to come in,
and tell us which packages you want to
still be pulled from the upstream.
I ran into essentially going in,
and doing it an npm install with a bunch of outdated packages.
Then essentially trying to upgrade
them while having this lock here.
But all I do know is that that was the problem,
and that's how I fixed it.
All I did really was delete the feed.
I literally just deleted the feed.
I came in here, and I clicked "Delete Feed",
and then I went into my Deleted Feeds,
and then you can click on it here.
Then if you click on the settings for that,
you can permanently delete it.
Just to note, when you delete a feed,
it stays in your account for 30 days because they're like,
hey, there's a lot of stuff in here,
I don't know if you just want us to delete it right away.
But you can actually speed up
that process if you want to by just clicking on this,
going to Deleted Feeds, clicking on that feed,
and then going to the same settings.
When you go to the same settings, you'll actually see,
permanently delete feed,
and then it'll be gone within 10-15 minutes.
You'll notice that again now if we go to mypackage.json,
everything is exactly locked now.
Now that we've got that,
let's go ahead, and do a couple of things.
Because I did get this repository completely working,
so I'm going to tell it to install,
I'm going to tell it to run jest,
and actually tell it to do npm run-script-build.
If I go in here you'll see I have an index.ts,
and an index.js after I run those commands,
and build everything, it's actually a boat.
But I really only want this package
to have the JavaScript definitions, and everything like that.
On top of it, I want to make it so that I can easily add
these pieces of logic to this module or to this library.
If we go to index.ts,
we're actually going to see that we
basically just have a file here
that literally goes out into each lib file,
and then just exports them.
You basically are barreling all of your code where you're
essentially rolling it from TypeScript
to JavaScript by using these exports here.
What's going to happen is this code,
when it gets built,
it's going to change it from TypeScript to JavaScript.
What's happening now is that it's literally building
the JavaScript files in the same path as the TypeScript files.
When we go to publish this code,
we're not going to include the native TypeScript file.
This is my normal code on the left,
and then this over here is my auto-generated code.
Because of how JavaScript or node works,
essentially, it's going to infer based off of the language.
Well, I see that this has a file here called lib access token.
What's the most available file to me?
It doesn't care if it's JavaScript or TypeScript.
This index.js, if we publish it with the package,
will load this accesstoken.js
not the ts because we're not going to include it in the package.
But we do want this file right here.
That's a definition file.
Definition files are for the compatibility on the TypeScript side.
In your Gitignore all you have to do is say, hey,
ignore anything in my repository,
in my lib folder,
that's a JavaScript file,
and a type definition,
and in my main route,
ignore anything that's a JavaScript file,
and a type definition for index.
This way, make sure that the paths are always the same,
that files are always in the place that I expect them to be,
and I don't have to worry
about forgetting something, essentially.
This is the second thing I want to show you guys.
Now if I go to npmignore I have again the ignoring of js,
the dts, the index.js, and the index.dts.
But let's look at my npmignore,
it's literally the opposite.
In here I'm saying I want you ignore my TypeScript files,
and I want you to also not ignore everything that is a d.ts file.
With that, I'm going to run it clean one more time,
and now I'm going do npm run-script built.
The name of the package I'm going to
release is quirk service, and it's going to be scoped.
Let's do npm publish.
You see here it publishes quirk service at 010.
Only JavaScript here, npm-shrinkwrap, which is what we want,
package.json is what we want or README,
and then look at this only our TypeScript definitions.
One of the reasons why I like this too it is because I'm being
very explicit about what I want in this repository.
If somebody were to try,
and add something else,
it should be get ignored because if we use them right,
it doesn't really matter how you set up the repository.
You'll always make sure that you only put in what you want to.
Now, if I go into Azure's Artifacts,
I should be able to do /quirk, boom.
There's my service that I just pushed up.
Now I need to go to my api service,
and I need to add it as a node module.
That's one thing to note is if you want to
interface with Azure's Artifacts at all,
you need to make sure you have that npmrc in any of your projects.
Because if I do npm config get registry, you'll see that yes,
I am in fact connected,
and pointed to my npm registry on Azure.
I now have my npm module
with TypeScript support published to my own Azure.
We really want to get our api service to
be able to migrate against our Dev database in Azure.
Here's where things get really interesting.
If I do npm install,
it should just immediately install everything pretty quickly.
There we go, four seconds.
Now if I do npm run-script build,
all of these imports are using
the local reference from my old mono repo.
These are all needed to be updated from
the local imports to our new node module that we're using.
We have the module imported,
we know it works,
but now we're going to need to go into all of these places,
and quickly fix their imports.
There's about 151 of these places we got to go through.
This is hands down one of
the most difficult services to
migrate just because there's so much logic in it,
let's just knock these out directly, twitch stream,
here is the body.data.
I need to get the body off of the request.
That fixed that.
Where we're leaving this right now is essentially,
I need to fix these last seven errors.
I'll then be able to start
running the pipelines, and all that stuff.
If we look at this chart that I've got here,
you're basically going to see that it starts from Azure DevOps.
Azure DevOps essentially is going to trigger a pipeline.
It's going to first build the container image in
a development state where it has
all the development packages it needs, and everything else.
Then it's going to build it in a production state.
The production image will just be
the flat optimized production image.
Once we build that Dev image,
that's going to actually get pushed up.
We'll use their container registry as an image.
The pipeline is going to say,
hey, I need you to go out,
and migrate all of
the database data for this specific environment,
run our tests against it,
run our migrations against it.
We can literally just reuse
this image or anything we need on our CI pipeline.
Even if we don't have to build again,
we don't have to do npm install again,
we don't have to do any of that stuff.
It's then going to immediately be executed in
a container with an entry point of Migrate.
The whole idea behind this,
the container is going to run,
and then it's going to die.
I don't want a pipeline to have to go out,
and have authentication,
and firewall rules,
and blah, blah, and [inaudible] whatever.
I just want to have that image that I need,
pushed up to the registry so that if I want to fire off
a one ad hoc container to go out to Postgres,
and make those migrations, then it will.