When someone deploys a contract on Ethereum (or any EVM-based blockchain) they are making a transaction not entirely unlike a regular transaction between two addresses (just with a lot of extra data). Just like any regular transaction is stored on the blockchain, so is a deployment. The deployer is the "from" address, so to speak.
Getting this address wouldn't be a function in Truffle, though. You'd need to scrape the blockchain using whichever library you use for interacting with the blockchain, though I am not sure exactly how to do this.
More to the point, if you are talking about accessing this data in Truffle tests, you should have an easier option - you will be deploying the contracts inside the test suite, so you should have the address natively available. For example, if you used:
let accounts = await web3.eth.getAccounts();
const deployer = accounts;
deployer to deploy your contracts in the tests, then you should have the address locally.
Another point worth mentioning: the
Ownable contracts from OpenZeppelin do not necessarily store the deployer of the contract in the
owner storage variable. While the default is that the deployer is set as the
owner at deploy, this can be changed afterwards (that's the point of the
renounceOwnership functions), so we're really talking about two different things when we talk about OpenZeppelin's
owner and the data in the actual blockchain, which will always be the deployer.
Hope this helps!