One of the big tricks I have found is that you actually have to identify everything that might need to be done to get something to "release" (whatever that means in your org). I don't mean like in waterfall with every individual thing in a project plan with an estimate. I mean in general for all stories. i.e. Definition of Done. Then, you identify the things that can and must be done during the story Sprint and that is the sprint definition of done. What is left over can be called release definition of done, and is work that some one has to do before a change can be released. Which requires that time and resources be allocated to accomplish those things after the sprint. And, it also requires acknowledging that every one of those items that was not done during the sprint creates a risk. Typically, to the release schedule. I would argue that the perfection goal if for most "release" definition of done items to be optional, and assessed as to whether the cost of doing that thing is worth the risk that something it could catch is in the code and gets in front of a customer. For example: Does every release require a full at scale performance and scalability test that is costly and might take a lot of time? Or, is it better to assess the changes and take the calculated and explicitly stated risk that the probability of a significant problem is small versus the benefit of putting the changes into production and detecting and fixing the less significant problems later. Non-optional items to be done after the sprint are high risk in that they are probably non-optional because they have a high chance of detecting issues that would prevent the release. ie. post-sprint functional testing.
It does require being brutally honest about whether a story is complete according to the Sprint Definition of Done, if it is not done, it is not done and must be moved to another sprint (preferably the next sprint). Unfortunately, most management does not want honesty or reality. They prefer their illusions of control because when handed actual reality they then have to do something about it and realize that they don't have any actual control over what goes on in their organization. So, you get blame and punishment which simply results in everyone pretending something is done when it really is not. Which allows everyone can spend quite a while being happy until the whole thing blows up in their faces.
This is the great thing about waterfall, you can produce requirements and design documents on schedule and everyone thinks all is well. Then, you can spend a bunch of time writing code that may or may not actually work. Then, at code complete you pretend you are actually done, but you know there is a bunch of time for defect fixes during test, plus you are going to have to implement new features because a business opportunity came up that is very valuable and it was decided that it could be implemented while everything else was tested. Even during testing with defects being found everyone is fairly happy because defects are expected. But, sometime during test reality finally slaps everyone and it is realized the schedule is impossible, a lot of things are not really done, there are too many defects. So, we go about punishing everyone. Testers and developers work a bunch of over time. PMs and Managers have to get yelled at by their superiors, everyone looks for some one to blame for the bad code. People spend days trying to figure out how much the actual release is going to slip, until finally some one decides the product is good enough and it goes to production with great fanfare. And, we repeat everything all over again.
Returning back to how to deal with this in Agile, consider the situation where testing is manual, significant chunks can slip out of the sprint definition of done. Or, you can end up doing mini waterfall inside the sprints where days are set aside at the end for testing. What often gets forgotten is the continuous improvement part of Agile or Lean, or whatever you want to call it. Perhaps no one is setting aside time to move tests from manual to automated. It can be a big bang or it can be a matter of all new tests and a portion of old tests every sprint to gradually free up the testers from being human script runners to spending more time figuring out what the tests are or doing the things humans do better like verify the UI visually, or try to find the weird edge cases that are hard to think of when the application is not right there in front of you (exploratory testing).